{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Title: #Search in Rotated Sorted Array"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Difficulty: #Medium"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Category Title: #Algorithms"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tag Slug: #array #binary-search"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Name Translated: #数组 #二分查找"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution Name: search"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Title: #搜索旋转排序数组"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Content:\n",
    "<p>整数数组 <code>nums</code> 按升序排列，数组中的值 <strong>互不相同</strong> 。</p>\n",
    "\n",
    "<p>在传递给函数之前，<code>nums</code> 在预先未知的某个下标 <code>k</code>（<code>0 &lt;= k &lt; nums.length</code>）上进行了 <strong>旋转</strong>，使数组变为 <code>[nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]</code>（下标 <strong>从 0 开始</strong> 计数）。例如， <code>[0,1,2,4,5,6,7]</code> 在下标 <code>3</code> 处经旋转后可能变为&nbsp;<code>[4,5,6,7,0,1,2]</code> 。</p>\n",
    "\n",
    "<p>给你 <strong>旋转后</strong> 的数组 <code>nums</code> 和一个整数 <code>target</code> ，如果 <code>nums</code> 中存在这个目标值 <code>target</code> ，则返回它的下标，否则返回&nbsp;<code>-1</code>&nbsp;。</p>\n",
    "\n",
    "<p>你必须设计一个时间复杂度为 <code>O(log n)</code> 的算法解决此问题。</p>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>示例 1：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>nums = [<code>4,5,6,7,0,1,2]</code>, target = 0\n",
    "<strong>输出：</strong>4\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例&nbsp;2：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>nums = [<code>4,5,6,7,0,1,2]</code>, target = 3\n",
    "<strong>输出：</strong>-1</pre>\n",
    "\n",
    "<p><strong>示例 3：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>nums = [1], target = 0\n",
    "<strong>输出：</strong>-1\n",
    "</pre>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>提示：</strong></p>\n",
    "\n",
    "<ul>\n",
    "\t<li><code>1 &lt;= nums.length &lt;= 5000</code></li>\n",
    "\t<li><code>-10<sup>4</sup> &lt;= nums[i] &lt;= 10<sup>4</sup></code></li>\n",
    "\t<li><code>nums</code> 中的每个值都 <strong>独一无二</strong></li>\n",
    "\t<li>题目数据保证 <code>nums</code> 在预先未知的某个下标上进行了旋转</li>\n",
    "\t<li><code>-10<sup>4</sup> &lt;= target &lt;= 10<sup>4</sup></code></li>\n",
    "</ul>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Description: [search-in-rotated-sorted-array](https://leetcode.cn/problems/search-in-rotated-sorted-array/description/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solutions: [search-in-rotated-sorted-array](https://leetcode.cn/problems/search-in-rotated-sorted-array/solutions/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_cases = ['[4,5,6,7,0,1,2]\\n0', '[4,5,6,7,0,1,2]\\n3', '[1]\\n0']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import Counter\n",
    "import bisect\n",
    "\n",
    "class TopVotedCandidate:\n",
    "    def __init__(self, persons: List[int], times: List[int]):\n",
    "        self.perVotedTime_Dic = dict()\n",
    "        for i, p in enumerate(persons):\n",
    "            if p not in self.perVotedTime_Dic.keys():\n",
    "                self.perVotedTime_Dic[p] = list()\n",
    "            self.perVotedTime_Dic[p].append(times[i])\n",
    "        print(self.perVotedTime_Dic)\n",
    "\n",
    "    def search_left(self):\n",
    "        pass\n",
    "\n",
    "    def q(self, t: int) -> int:\n",
    "        votedCnt = 0\n",
    "        res_people = -1\n",
    "        nearlst_cur = -1\n",
    "        for people in self.perVotedTime_Dic.keys():\n",
    "            TimeList = self.perVotedTime_Dic[people]\n",
    "            idx = bisect.bisect_right(TimeList, t) - 1\n",
    "            if idx+1 > votedCnt or (idx+1 == votedCnt and TimeList[idx] > nearlst_cur):\n",
    "                votedCnt = idx + 1\n",
    "                res_people = people\n",
    "                nearlst_cur = TimeList[idx]\n",
    "                \n",
    "        return res_people\n",
    "\n",
    "\n",
    "# Your TopVotedCandidate object will be instantiated and called as such:\n",
    "# obj = TopVotedCandidate(persons, times)\n",
    "# param_1 = obj.q(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class MajorityChecker:\n",
    "    def __init__(self, arr):\n",
    "        self.arr = arr\n",
    "        self.freq = {}\n",
    "        for i, num in enumerate(arr):\n",
    "            if num not in self.freq:\n",
    "                self.freq[num] = []\n",
    "            self.freq[num].append(i)\n",
    "    \n",
    "    def count_occurrences(self, num, left, right):\n",
    "        # Find the number of occurrences of num between left and right using binary search\n",
    "        left_indices = self.freq.get(num, [])\n",
    "        start = 0\n",
    "        end = len(left_indices) - 1\n",
    "        \n",
    "        # Find the start index\n",
    "        while start <= end:\n",
    "            mid = (start + end) // 2\n",
    "            if left_indices[mid] < left:\n",
    "                start = mid + 1\n",
    "            else:\n",
    "                end = mid - 1\n",
    "        start_idx = start\n",
    "        \n",
    "        # Find the end index\n",
    "        start = 0\n",
    "        end = len(left_indices) - 1\n",
    "        while start <= end:\n",
    "            mid = (start + end) // 2\n",
    "            if left_indices[mid] <= right:\n",
    "                start = mid + 1\n",
    "            else:\n",
    "                end = mid - 1\n",
    "        end_idx = end\n",
    "        \n",
    "        return end_idx - start_idx + 1\n",
    "\n",
    "    def query(self, left, right, threshold):\n",
    "        for _ in range(20):  # Try 20 times\n",
    "            idx = random.randint(left, right)\n",
    "            num = self.arr[idx]\n",
    "            if self.count_occurrences(num, left, right) >= threshold:\n",
    "                return num\n",
    "        return -1\n",
    "\n",
    "\n",
    "# Your MajorityChecker object will be instantiated and called as such:\n",
    "# obj = MajorityChecker(arr)\n",
    "# param_1 = obj.query(left,right,threshold)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def openLock(self, deadends, target):\n",
    "        \"\"\"\n",
    "        :type deadends: List[str]\n",
    "        :type target: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        from collections import deque\n",
    "        step = 0\n",
    "        v_search_queue = deque()\n",
    "        v_search_queue.append((step, '0000'))\n",
    "        v_visited = set(deadends)\n",
    "        \n",
    "        while v_search_queue:\n",
    "            temp = v_search_queue.popleft()\n",
    "            step_now = temp[0]\n",
    "            vertical_now = temp[1]\n",
    "\n",
    "            if vertical_now not in v_visited:\n",
    "                if vertical_now == target:\n",
    "                    return step_now\n",
    "                v_visited.add(vertical_now)\n",
    "                out = self.get_no_visited_neighbors(vertical_now, v_visited)\n",
    "                if out:\n",
    "                    out_new = [(step_now + 1, x) for x in out]\n",
    "                    v_search_queue.extend(out_new)\n",
    "\n",
    "        return -1\n",
    "    \n",
    "    def get_no_visited_neighbors(self, this_num, visited_list):\n",
    "\n",
    "        out = list()\n",
    "        for i, each in enumerate(this_num):\n",
    "            each_new = (int(each) + 1) % 10\n",
    "            each_new = str(each_new)\n",
    "            str_new = this_num[:i] + each_new + this_num[i + 1:]\n",
    "            if str_new not in visited_list:\n",
    "                out.append(str_new)\n",
    "            each_new = (int(each) - 1) % 10\n",
    "            each_new = str(each_new)\n",
    "            str_new = this_num[:i] + each_new + this_num[i + 1:]\n",
    "            if str_new not in visited_list:\n",
    "                out.append(str_new)\n",
    "        return out"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def openLock(self, deadends, target):\n",
    "        \"\"\"\n",
    "        :type deadends: List[str]\n",
    "        :type target: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        begin = [\"0000\", 0]\n",
    "        search = collections.deque()\n",
    "        dead_set = set(deadends)\n",
    "        used = set()\n",
    "\n",
    "        if begin[0] not in dead_set:\n",
    "            search.append(begin)\n",
    "            used.add(begin[0])\n",
    "        else:\n",
    "            return -1\n",
    "\n",
    "        while search:\n",
    "            seed = search.popleft()\n",
    "            code = seed[0]\n",
    "            step = seed[1]\n",
    "\n",
    "            step += 1\n",
    "            for i in range(4):\n",
    "                new_code = code[0:i] + str((int(code[i]) + 1) % 10) + code[i + 1:]\n",
    "\n",
    "                if new_code not in dead_set and new_code not in used and new_code != target:\n",
    "                    search.append([new_code, step])\n",
    "                    used.add(new_code)\n",
    "                elif new_code == target:\n",
    "                    return step\n",
    "\n",
    "                new_code = code[0:i] + str((int(code[i]) - 1) % 10) + code[i + 1:]\n",
    "                if new_code not in dead_set and new_code not in used and new_code != target:\n",
    "                    search.append([new_code, step])\n",
    "                    used.add(new_code)\n",
    "                elif new_code == target:\n",
    "                    return step\n",
    "\n",
    "        return -1        \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class LockingTree:\n",
    "\n",
    "    def __init__(self, parent: List[int]):\n",
    "        # {num: [True/False, user, father]}\n",
    "        self.info = defaultdict(lambda: [False, -1, -1])\n",
    "        self.children = defaultdict(list)  # {father: [children]}\n",
    "        for son, father in enumerate(parent):\n",
    "            self.info[son][2] = father\n",
    "            self.children[father].append(son)\n",
    "\n",
    "    def lock(self, num: int, user: int) -> bool:\n",
    "        \"\"\"\n",
    "        指定用户给指定节点 上锁 ，上锁后其他用户将无法给同一节点上锁。只有当节点处于未上锁的状态下，才能进行上锁操作\n",
    "        如果 id 为 user 的用户可以给节点 num 上锁，那么返回 true ，否则返回 false 。\n",
    "        如果可以执行此操作，节点 num 会被 id 为 user 的用户 上锁 。\n",
    "        \"\"\"\n",
    "        if self.info[num][0] is False:\n",
    "            self.info[num][0] = True\n",
    "            self.info[num][1] = user\n",
    "            return True\n",
    "        return False\n",
    "\n",
    "    def unlock(self, num: int, user: int) -> bool:\n",
    "        \"\"\"\n",
    "        指定用户给指定节点 解锁 ，只有当指定节点当前正被指定用户锁住时，才能执行该解锁操作。\n",
    "        如果 id 为 user 的用户可以给节点 num 解锁，那么返回 true ，否则返回 false 。\n",
    "        如果可以执行此操作，节点 num 变为 未上锁 状态。\n",
    "        \"\"\"\n",
    "        if self.info[num][0] is True and self.info[num][1] == user:\n",
    "            self.info[num][0] = False\n",
    "            self.info[num][1] = -1\n",
    "            return True\n",
    "        return False\n",
    "\n",
    "    def upgrade(self, num: int, user: int) -> bool:\n",
    "        \"\"\"\n",
    "        指定用户给指定节点 上锁 ，并且将该节点的所有子孙节点 解锁 。只有如下 3 个条件 全部 满足时才能执行升级操作：\n",
    "        指定节点当前状态为未上锁。\n",
    "        指定节点至少有一个上锁状态的子孙节点（可以是 任意 用户上锁的）。\n",
    "        指定节点没有任何上锁的祖先节点。\n",
    "        如果 id 为 user 的用户可以给节点 num 升级，那么返回 true ，否则返回 false 。\n",
    "        如果可以执行此操作，节点 num 会被 升级 。\n",
    "        \"\"\"\n",
    "        # 指定节点当前状态为未上锁\n",
    "        if self.info[num][0] is True:\n",
    "            return False\n",
    "\n",
    "        # 指定节点至少有一个上锁状态的子孙节点（可以是 任意 用户上锁的）\n",
    "        lockedChildren = self.searchLockedChild(num, [])  # 记录上锁的子孙节点\n",
    "        if not lockedChildren:\n",
    "            return False\n",
    "\n",
    "        # 指定节点没有任何上锁的祖先节点\n",
    "        hasLockedParents = self.searchLockedParents(num)\n",
    "        if hasLockedParents is True:\n",
    "            return False\n",
    "\n",
    "        # 以上3个条件都满足, 可以进行升级操作\n",
    "        # 指定用户给指定节点 上锁 ，并且将该节点的所有子孙节点 解锁\n",
    "        self.info[num][0], self.info[num][1] = True, user\n",
    "        for child in lockedChildren:\n",
    "            self.info[child][0] = False\n",
    "            self.info[child][1] = -1\n",
    "        return True\n",
    "\n",
    "    # 查找并返回上锁的子孙节点\n",
    "    def searchLockedChild(self, num: int, lockedChildren: list):\n",
    "        if self.info[num][0] is True:\n",
    "            lockedChildren.append(num)\n",
    "\n",
    "        if self.children[num]:\n",
    "            for child in self.children[num]:\n",
    "                self.searchLockedChild(child, lockedChildren)\n",
    "        return lockedChildren\n",
    "\n",
    "    # 查找上锁的祖先, 有返回True, 没有返回False\n",
    "    def searchLockedParents(self, num):\n",
    "        if self.info[num][0] is True:\n",
    "            return True\n",
    "\n",
    "        father = self.info[num][2]\n",
    "        if father != -1:\n",
    "            return self.searchLockedParents(father)\n",
    "        return False\n",
    "\n",
    "\n",
    "\n",
    "# Your LockingTree object will be instantiated and called as such:\n",
    "# obj = LockingTree(parent)\n",
    "# param_1 = obj.lock(num,user)\n",
    "# param_2 = obj.unlock(num,user)\n",
    "# param_3 = obj.upgrade(num,user)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class LockingTree:\n",
    "\n",
    "    def __init__(self, parent: List[int]):\n",
    "        # {num: [True/False, user, father]}\n",
    "        self.info = defaultdict(lambda: [False, -1, -1])\n",
    "        self.children = defaultdict(list)  # {father: [children]}\n",
    "        for son, father in enumerate(parent):\n",
    "            self.info[son][2] = father\n",
    "            self.children[father].append(son)\n",
    "\n",
    "    def lock(self, num: int, user: int) -> bool:\n",
    "        if self.info[num][0] is False:\n",
    "            self.info[num][0] = True\n",
    "            self.info[num][1] = user\n",
    "            return True\n",
    "        return False\n",
    "\n",
    "    def unlock(self, num: int, user: int) -> bool:\n",
    "        if self.info[num][0] is True and self.info[num][1] == user:\n",
    "            self.info[num][0] = False\n",
    "            self.info[num][1] = -1\n",
    "            return True\n",
    "        return False\n",
    "\n",
    "    def upgrade(self, num: int, user: int) -> bool:\n",
    "        # 指定节点当前状态为未上锁\n",
    "        if self.info[num][0] is True:\n",
    "            return False\n",
    "\n",
    "        # 指定节点至少有一个上锁状态的子孙节点（可以是 任意 用户上锁的）\n",
    "        @ cache\n",
    "        def searchLockedChild(num):\n",
    "            if self.info[num][0] is True:\n",
    "                lockedChildren.append(num)\n",
    "            if not self.children[num]:\n",
    "                return\n",
    "            for child in self.children[num]:\n",
    "                searchLockedChild(child)\n",
    "\n",
    "        lockedChildren = []  # 记录上锁的子孙节点\n",
    "        searchLockedChild(num)\n",
    "        if not lockedChildren:\n",
    "            return False\n",
    "\n",
    "        @ cache\n",
    "        def searchParents(num):\n",
    "            if self.info[num][0] is True:\n",
    "                return True\n",
    "\n",
    "            father = self.info[num][2]\n",
    "            if father != -1:\n",
    "                return searchParents(father)\n",
    "            return False\n",
    "\n",
    "        hasLockedParents = searchParents(num)\n",
    "        if hasLockedParents is True:\n",
    "            return False\n",
    "\n",
    "        # 以上3个条件都满足, 可以进行升级操作\n",
    "        # 指定用户给指定节点 上锁 ，并且将该节点的所有子孙节点 解锁\n",
    "        self.info[num][0], self.info[num][1] = True, user\n",
    "        for child in lockedChildren:\n",
    "            self.info[child][0] = False\n",
    "            self.info[child][1] = -1\n",
    "        return True\n",
    "\n",
    "\n",
    "\n",
    "# Your LockingTree object will be instantiated and called as such:\n",
    "# obj = LockingTree(parent)\n",
    "# param_1 = obj.lock(num,user)\n",
    "# param_2 = obj.unlock(num,user)\n",
    "# param_3 = obj.upgrade(num,user)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def findTarget(self, root: TreeNode, k: int) -> bool:\n",
    "        dic = {}\n",
    "        def search(root):\n",
    "            if root is None:\n",
    "                return False\n",
    "            if k-root.val in dic:\n",
    "                return True\n",
    "            dic[root.val]=0\n",
    "            return search(root.left) or search(root.right)\n",
    "        return search(root)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def findTarget(self, root: TreeNode, k: int) -> bool:\n",
    "        self.hashmap=dict()\n",
    "        return self.search(root, k)\n",
    "    \n",
    "    def search(self, node, k):\n",
    "        if not node:\n",
    "            return False\n",
    "        if k-node.val in self.hashmap:\n",
    "            return True\n",
    "        self.hashmap[node.val]=1\n",
    "        left=self.search(node.left, k)\n",
    "        if left:\n",
    "            return left\n",
    "        right=self.search(node.right, k)\n",
    "        if right:\n",
    "            return right\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findPaths(self, m: int, n: int, maxMove: int, startRow: int, startColumn: int) -> int:\n",
    "\n",
    "        mod=10**9+7\n",
    "\n",
    "        @cache\n",
    "\n",
    "        def search(r,c,move):\n",
    "            if r==-1 or c==-1 or c==n or r==m:\n",
    "                return 1\n",
    "            else:\n",
    "                if move==0:\n",
    "                    return 0\n",
    "                else:\n",
    "                    return search(r,c-1,move-1)+search(r,c+1,move-1)+search(r-1,c,move-1)+search(r+1,c,move-1)\n",
    "\n",
    "\n",
    "        return search(startRow,startColumn,maxMove)%mod"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def inorderSuccessor(self, root: 'TreeNode', p: 'TreeNode') -> 'TreeNode':\n",
    "        self.res=TreeNode(100001)\n",
    "        self.search(root, p)\n",
    "        if self.res.val==100001:\n",
    "            return None\n",
    "        else:\n",
    "            return self.res\n",
    "\n",
    "    def search(self, node, p):\n",
    "        if not node:\n",
    "            return\n",
    "        self.search(node.left, p)\n",
    "        if node.val>p.val:\n",
    "            if node.val<self.res.val:\n",
    "                self.res=node\n",
    "        self.search(node.right, p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def inorderSuccessor(self, root: TreeNode, p: TreeNode) -> Optional[TreeNode]:\n",
    "        # 有右子树的情况\n",
    "        if p.right != None:\n",
    "            ans = p.right\n",
    "            while ans.left:\n",
    "                ans = ans.left\n",
    "            return ans\n",
    "\n",
    "        # 没有右子树时，若p为父节点的右节点，\n",
    "        # 弹出，直到找到第一个左节点的父节点\n",
    "        \n",
    "        parents = []\n",
    "        def search(root):\n",
    "            if root is None:\n",
    "                return False\n",
    "            if root == p: # 回溯\n",
    "                return True\n",
    "            parents.append(root)\n",
    "            if search(root.left):\n",
    "                return True\n",
    "            if search(root.right):\n",
    "                return True\n",
    "            parents.pop()\n",
    "            return False\n",
    "        search(root)\n",
    "        \n",
    "        while parents and parents[-1].right == p:\n",
    "            p = parents.pop()\n",
    "\n",
    "        if parents:\n",
    "            return parents[-1]\n",
    "        else:\n",
    "            return None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def pacificAtlantic(self, matrix):\n",
    "        \"\"\"\n",
    "        :type matrix: List[List[int]]\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "\n",
    "        if not matrix:\n",
    "            return []\n",
    "        step = [[-1, 0], [1, 0], [0, -1], [0, 1]]  # 上下左右四个方向\n",
    "        result_list = []\n",
    "        m = len(matrix)\n",
    "        n = len(matrix[0])\n",
    "\n",
    "        # DFS+记忆存储\n",
    "        p_flag = [[False]*n for _ in range(m)]  # 有哪些格子能够流入太平洋\n",
    "        a_flag = [[False]*n for _ in range(m)]  # 有哪些格子能够流入大西洋\n",
    "\n",
    "        # 从四条边开始\n",
    "        for row_idx in range(m):\n",
    "            # 左边的列\n",
    "            self.dfs_search(row_idx, 0, p_flag, step, m, n, matrix)\n",
    "            # 右边的列\n",
    "            self.dfs_search(row_idx, n-1, a_flag, step, m, n, matrix)\n",
    "\n",
    "        for col_idx in range(n):\n",
    "            # 上边的行\n",
    "            self.dfs_search(0, col_idx, p_flag, step, m, n, matrix)\n",
    "            # 下边的行\n",
    "            self.dfs_search(m-1, col_idx, a_flag, step, m, n, matrix)\n",
    "\n",
    "        for row_idx in range(m):\n",
    "            for col_idx in range(n):\n",
    "                if p_flag[row_idx][col_idx] and a_flag[row_idx][col_idx]:\n",
    "                    result_list.append([row_idx, col_idx])\n",
    "        return result_list\n",
    "\n",
    "    def dfs_search(self, row_num, col_num, visited_matrix, step, m, n, matrix):\n",
    "        # 能够进入就表明当前格子可以被访问\n",
    "        visited_matrix[row_num][col_num] = True\n",
    "        for x, y in step:\n",
    "            # 遍历上下左右，让水流逆流而上\n",
    "            new_row = row_num+x\n",
    "            new_col = col_num+y\n",
    "            # 找到可以顺流而上的条件，在格子内，周边格子高度比当前高，且周边格子还没走过\n",
    "            if 0 <= new_row < m and 0 <= new_col < n and matrix[new_row][new_col] >= matrix[row_num][col_num] \\\n",
    "                    and visited_matrix[new_row][new_col] is False:\n",
    "                self.dfs_search(new_row, new_col, visited_matrix, step, m, n, matrix)\n",
    "\n",
    "        return"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def pacificAtlantic(self, matrix):\n",
    "        \"\"\"\n",
    "        :type matrix: List[List[int]]\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "\n",
    "        # 采用DFS+剪枝\n",
    "        if not matrix:\n",
    "            return []\n",
    "        m = len(matrix)\n",
    "        n = len(matrix[0])\n",
    "\n",
    "        # 将已经搜索过的格子建立成字典，达到剪枝的效果\n",
    "        # key表示格子坐标，(row_idx, col_idx)\n",
    "        # value是两个bit的整数，第0bit表示能否流向太平洋，第1bit表示能否流向大西洋\n",
    "        # bit为0表示不能流向，为1表示能够流入\n",
    "        flow_dict = dict()\n",
    "        result_list = []\n",
    "\n",
    "        # 接下来采用DFS进行搜索，从四条边开始往中间搜索\n",
    "        min_dim = min(m, n)\n",
    "        half_min_dim = min_dim // 2 + min_dim % 2\n",
    "        for layer_idx in range(half_min_dim):\n",
    "            # 处理两列\n",
    "            for row_idx in range(layer_idx, m-layer_idx):\n",
    "                # 左边的一列\n",
    "                search_matrix = [[0]*n for _ in range(m)]  # 每个网格搜索时候存储中间搜索状态的矩阵\n",
    "                flow_dict[(row_idx, layer_idx)] = self.dfs_search(matrix, row_idx, layer_idx, result_list, flow_dict,\n",
    "                                                                  m, n, search_matrix)\n",
    "                if flow_dict[(row_idx, layer_idx)] is 3:\n",
    "                    result_list.append([row_idx, layer_idx])\n",
    "\n",
    "                # 右边的一列\n",
    "                if (row_idx, n-layer_idx-1) not in flow_dict:\n",
    "                    search_matrix = [[0]*n for _ in range(m)]  # 每个网格搜索时候存储中间搜索状态的矩阵\n",
    "                    flow_dict[(row_idx, n-layer_idx-1)] = self.dfs_search(matrix, row_idx, n-layer_idx-1, result_list,\n",
    "                                                                          flow_dict, m, n, search_matrix)\n",
    "                    if flow_dict[(row_idx, n-layer_idx-1)] is 3:\n",
    "                        result_list.append([row_idx, n-layer_idx-1])\n",
    "\n",
    "            # 处理两行\n",
    "            for col_idx in range(layer_idx+1, n-layer_idx-1):\n",
    "                # 上边的一行\n",
    "                if (layer_idx, col_idx) not in flow_dict:\n",
    "                    search_matrix = [[0]*n for _ in range(m)]  # 每个网格搜索时候存储中间搜索状态的矩阵\n",
    "                    flow_dict[(layer_idx, col_idx)] = self.dfs_search(matrix, layer_idx, col_idx, result_list, flow_dict,\n",
    "                                                                      m, n, search_matrix)\n",
    "                    if flow_dict[(layer_idx, col_idx)] is 3:\n",
    "                        result_list.append([layer_idx, col_idx])\n",
    "\n",
    "                # 下边的一行\n",
    "                if (m-layer_idx-1, col_idx) not in flow_dict:\n",
    "                    search_matrix = [[0]*n for _ in range(m)]  # 每个网格搜索时候存储中间搜索状态的矩阵\n",
    "                    flow_dict[(m-layer_idx-1, col_idx)] = self.dfs_search(matrix, m-layer_idx-1, col_idx, result_list,\n",
    "                                                                          flow_dict, m, n, search_matrix)\n",
    "                    if flow_dict[(m-layer_idx-1, col_idx)] is 3:\n",
    "                        result_list.append([m-layer_idx-1, col_idx])\n",
    "\n",
    "        # for row_idx in range(m):\n",
    "        #     for col_idx in range(n):\n",
    "        #         search_matrix = [[0]*n for _ in range(m)]  # 每个网格搜索时候存储中间搜索状态的矩阵\n",
    "        #         flow_dict[(row_idx, col_idx)] = self.dfs_search(matrix, row_idx, col_idx, result_list, flow_dict, m, n,\n",
    "        #                                                         search_matrix)\n",
    "        #         if flow_dict[(row_idx, col_idx)] is 3:\n",
    "        #             result_list.append([row_idx, col_idx])\n",
    "\n",
    "        return result_list\n",
    "\n",
    "    def dfs_search(self, matrix, row_num, col_num, result_list, flow_dict, m, n, search_matrix):\n",
    "        if (row_num, col_num) in flow_dict:\n",
    "            # 直接返回已有结果\n",
    "            return flow_dict[(row_num, col_num)]\n",
    "        else:\n",
    "            # 查看上下左右有没有可以流动的方向\n",
    "            # 如果在搜索中碰到上下左右的search_matrix有为4的，就放弃这条路径\n",
    "\n",
    "            # 检查上边网格\n",
    "            if row_num is 0:\n",
    "                # 可以流入太平洋\n",
    "                search_matrix[row_num][col_num] |= 1\n",
    "            elif matrix[row_num][col_num] >= matrix[row_num-1][col_num]:\n",
    "                if search_matrix[row_num-1][col_num] is 4:\n",
    "                    # 放弃这个方向，因为搜索就是从这个方向过来的\n",
    "                    pass\n",
    "                else:\n",
    "                    store_val = search_matrix[row_num][col_num]\n",
    "                    search_matrix[row_num][col_num] = 4\n",
    "                    tmp_result = self.dfs_search(matrix, row_num-1, col_num, result_list, flow_dict, m, n, search_matrix)\n",
    "                    search_matrix[row_num][col_num] = store_val | tmp_result\n",
    "            else:\n",
    "                search_matrix[row_num][col_num] |= 0\n",
    "\n",
    "            if search_matrix[row_num][col_num] is 3:\n",
    "                return 3\n",
    "\n",
    "            # 检查下边网格\n",
    "            if row_num is m-1:\n",
    "                # 可以流入大西洋\n",
    "                search_matrix[row_num][col_num] |= 2\n",
    "            elif matrix[row_num][col_num] >= matrix[row_num+1][col_num]:\n",
    "                if search_matrix[row_num+1][col_num] is 4:\n",
    "                    # 放弃这个方向，因为搜索就是从这个方向过来的\n",
    "                    pass\n",
    "                else:\n",
    "                    store_val = search_matrix[row_num][col_num]\n",
    "                    search_matrix[row_num][col_num] = 4\n",
    "                    tmp_result = self.dfs_search(matrix, row_num+1, col_num, result_list, flow_dict, m, n, search_matrix)\n",
    "                    search_matrix[row_num][col_num] = store_val | tmp_result\n",
    "            else:\n",
    "                search_matrix[row_num][col_num] |= 0\n",
    "\n",
    "            if search_matrix[row_num][col_num] is 3:\n",
    "                return 3\n",
    "\n",
    "            # 检查左边网格\n",
    "            if col_num is 0:\n",
    "                # 可以流入太平洋\n",
    "                search_matrix[row_num][col_num] |= 1\n",
    "            elif matrix[row_num][col_num] >= matrix[row_num][col_num-1]:\n",
    "                if search_matrix[row_num][col_num-1] is 4:\n",
    "                    # 放弃这个方向，因为搜索就是从这个方向过来的\n",
    "                    pass\n",
    "                else:\n",
    "                    store_val = search_matrix[row_num][col_num]\n",
    "                    search_matrix[row_num][col_num] = 4\n",
    "                    tmp_result = self.dfs_search(matrix, row_num, col_num-1, result_list, flow_dict, m, n, search_matrix)\n",
    "                    search_matrix[row_num][col_num] = store_val | tmp_result\n",
    "            else:\n",
    "                search_matrix[row_num][col_num] |= 0\n",
    "\n",
    "            if search_matrix[row_num][col_num] is 3:\n",
    "                return 3\n",
    "\n",
    "            # 检查右边网格\n",
    "            if col_num is n-1:\n",
    "                # 可以流入大西洋\n",
    "                search_matrix[row_num][col_num] |= 2\n",
    "            elif matrix[row_num][col_num] >= matrix[row_num][col_num+1]:\n",
    "                if search_matrix[row_num][col_num+1] is 4:\n",
    "                    # 放弃这个方向，因为搜索就是从这个方向过来的\n",
    "                    pass\n",
    "                else:\n",
    "                    store_val = search_matrix[row_num][col_num]\n",
    "                    search_matrix[row_num][col_num] = 4\n",
    "                    tmp_result = self.dfs_search(matrix, row_num, col_num+1, result_list, flow_dict, m, n, search_matrix)\n",
    "                    search_matrix[row_num][col_num] = store_val | tmp_result\n",
    "            else:\n",
    "                search_matrix[row_num][col_num] |= 0\n",
    "\n",
    "            return search_matrix[row_num][col_num]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:\n",
    "        m, n = len(heights), len(heights[0])\n",
    "\n",
    "        # 1.反向搜索: 从海岸线往山上跑\n",
    "        # def search(starts: List[Tuple[int, int]]) -> Set[Tuple[int, int]]:\n",
    "        #     visited = set()\n",
    "            \n",
    "        #     # 深度优先搜索: 递归\n",
    "        #     def dfs(x: int, y: int):\n",
    "        #         if (x, y) in visited:\n",
    "        #             return\n",
    "        #         visited.add((x, y))\n",
    "        #         for nx, ny in ((x, y + 1), (x, y - 1), (x - 1, y), (x + 1, y)):\n",
    "        #             if 0 <= nx < m and 0 <= ny < n and heights[nx][ny] >= heights[x][y]:\n",
    "        #                 dfs(nx, ny)\n",
    "            \n",
    "        #     for x, y in starts:\n",
    "        #         dfs(x, y)\n",
    "        #     return visited\n",
    "\n",
    "        # # 两个大洋的海岸线\n",
    "        # pacific = [(0, i) for i in range(n)] + [(i, 0) for i in range(1, m)]\n",
    "        # atlantic = [(m - 1, i) for i in range(n)] + [(i, n - 1) for i in range(m - 1)]\n",
    "        # # 将结果取与\n",
    "        # ans = list(map(list, search(pacific) & search(atlantic)))\n",
    "        # return ans\n",
    "\n",
    "        # 2.广度优先搜索: 借助队列\n",
    "        # def bfs(starts: List[Tuple[int, int]]) -> Set[Tuple[int, int]]:\n",
    "        #     q = deque(starts)\n",
    "        #     visited = set(starts)\n",
    "        #     while q:\n",
    "        #         x, y = q.popleft()\n",
    "        #         for nx, ny in ((x, y + 1), (x, y - 1), (x - 1, y), (x + 1, y)):\n",
    "        #             if 0 <= nx < m and 0 <= ny < n and heights[nx][ny] >= heights[x][y] and (nx, ny) not in visited:\n",
    "        #                 q.append((nx, ny))\n",
    "        #                 visited.add((nx, ny))\n",
    "        #     return visited\n",
    "        \n",
    "        # pacific = [(0, i) for i in range(n)] + [(i, 0) for i in range(1, m)]\n",
    "        # atlantic = [(m - 1, i) for i in range(n)] + [(i, n - 1) for i in range(m - 1)]\n",
    "        # ans = list(map(list, bfs(pacific) & bfs(atlantic)))\n",
    "        # return ans\n",
    "\n",
    "        row, col = len(heights), len(heights[0])\n",
    "\n",
    "        def search(starts: List[Tuple[int, int]]) -> Set[Tuple[int, int]]:\n",
    "            visited = set()\n",
    "\n",
    "            def dfs(x: int, y: int):\n",
    "                if (x, y) in visited:\n",
    "                    return\n",
    "                visited.add((x, y))\n",
    "                for tmpx, tmpy in ((x - 1, y), (x, y + 1), (x + 1, y), (x, y - 1)):\n",
    "                    if 0 <= tmpx < row and 0 <= tmpy < col and heights[tmpx][tmpy] >= heights[x][y]:\n",
    "                        dfs(tmpx, tmpy)\n",
    "            \n",
    "            for x, y in starts:\n",
    "                dfs(x, y)\n",
    "            return visited\n",
    "        \n",
    "        pacific = [(0, i) for i in range(0, col)] + [(i, 0) for i in range(row)]\n",
    "        atlantic = [(row - 1, i) for i in range(0, col)] + [(i, col - 1) for i in range(0, row)]\n",
    "        ans = [list(res) for res in search(pacific) & search(atlantic)]\n",
    "        return ans\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:\n",
    "        m,n = len(heights),len(heights[0])\n",
    "\n",
    "        def search(starts):\n",
    "            visited = set()\n",
    "            def dfs(x,y):\n",
    "                if (x,y) in visited:\n",
    "                    return\n",
    "                visited.add((x,y))\n",
    "                for nx, ny in ((x, y + 1), (x, y - 1), (x - 1, y), (x + 1, y)):\n",
    "                    if 0 <= nx < m and 0 <= ny < n and heights[nx][ny] >= heights[x][y]:\n",
    "                        dfs(nx, ny)\n",
    "\n",
    "            for x,y in starts:\n",
    "                dfs(x,y)\n",
    "            return visited\n",
    "\n",
    "        pacific = [(0, i) for i in range(n)] + [(i, 0) for i in range(1, m)]\n",
    "        atlantic = [(m - 1, i) for i in range(n)] + [(i, n - 1) for i in range(m - 1)]\n",
    "        return list(map(list,search(pacific) & search(atlantic)))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:\n",
    "        m, n = len(heights), len(heights[0])\n",
    "\n",
    "        def search(starts: List[Tuple[int, int]]) -> Set[Tuple[int, int]]:\n",
    "            visited = set()\n",
    "            def dfs(x: int, y: int):\n",
    "                if (x, y) in visited:\n",
    "                    return\n",
    "                visited.add((x, y))\n",
    "                for nx, ny in ((x, y + 1), (x, y - 1), (x - 1, y), (x + 1, y)):\n",
    "                    if 0 <= nx < m and 0 <= ny < n and heights[nx][ny] >= heights[x][y]:\n",
    "                        dfs(nx, ny)\n",
    "            for x, y in starts:\n",
    "                dfs(x, y)\n",
    "            return visited\n",
    "        \n",
    "        pacific = [(0, i) for i in range(n)] + [(i, 0) for i in range(1, m)]\n",
    "        atlantic = [(m - 1, i) for i in range(n)] + [(i, n - 1) for i in range(m - 1)]\n",
    "        return list(map(list, search(pacific) & search(atlantic)))\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def paintWalls(self, cost: List[int], time: List[int]) -> int:\n",
    "        n = len(cost)\n",
    "        MAX = sum(cost)\n",
    "\n",
    "        ss = list(zip(cost, time))\n",
    "        ss.sort(key=lambda x: (-x[1], x[0]))\n",
    "\n",
    "        acc = [0] * (n + 1)\n",
    "        for i in range(n):\n",
    "            acc[i + 1] = acc[i] + ss[i][1]\n",
    "\n",
    "        from functools import cache\n",
    "        @cache\n",
    "        def search(i, t):\n",
    "            if (t + acc[-1] - acc[i]) < 0: return MAX\n",
    "            if t >= (n - i): return 0\n",
    "\n",
    "            # what if paid\n",
    "            a = search(i + 1, t + ss[i][1]) + ss[i][0]\n",
    "            # what if free\n",
    "            b = search(i + 1, t - 1)\n",
    "            ans = min(a, b)\n",
    "            return ans\n",
    "\n",
    "        ans = search(0, 0)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPalindrome(self, head: ListNode) -> bool:\n",
    "        node1 = head\n",
    "        node2 = head\n",
    "        return self._search(node1) == self._search2(node2)\n",
    "\n",
    "    def _search(self, head):\n",
    "        if not head:\n",
    "            return \"\"\n",
    "        ans = self._search(head.next)\n",
    "        return ans + str(head.val)\n",
    "\n",
    "    def _search2(self, head):\n",
    "        if not head:\n",
    "            return \"\"\n",
    "        ans = str(head.val)\n",
    "        return ans + self._search2(head.next)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# 暴力（超时）\n",
    "# class Solution:\n",
    "#     def palindromePairs(self, words: List[str]) -> List[List[int]]:\n",
    "#         n = len(words)\n",
    "#         ans = []\n",
    "#         for i in range(n):\n",
    "#             for j in range(n):\n",
    "#                 if i!=j:\n",
    "#                     word = words[i]+words[j]\n",
    "#                     if word==word[::-1]:\n",
    "#                         ans.append([i,j])\n",
    "#         return ans\n",
    "\n",
    "# 哈希表\n",
    "# class Solution:\n",
    "#     def palindromePairs(self, words: List[str]) -> List[List[int]]:\n",
    "#         def is_palindrome(word,l,r):\n",
    "#             n = r-l+1\n",
    "#             return n<=1 or all(word[l+i]==word[l+n-i-1] for i in range(n//2))\n",
    "\n",
    "#         n = len(words)\n",
    "#         ans = []\n",
    "#         worddict = {word:i for i,word in enumerate(words)}\n",
    "#         for i,word in enumerate(words):\n",
    "#             m = len(word)\n",
    "#             for k in range(m+1):\n",
    "#                 prefix,suffix = word[:k][::-1],word[m-k:][::-1]\n",
    "#                 if prefix in worddict and i!=worddict[prefix] and is_palindrome(word,k,m-1):\n",
    "#                     ans.append([i,worddict[prefix]])\n",
    "#                 if k<m and suffix in worddict and i!=worddict[suffix] and is_palindrome(word,0,m-k-1):  # k<m避免镜像单词导致重复\n",
    "#                     ans.append([worddict[suffix],i])\n",
    "#         return ans\n",
    "\n",
    "# class Solution:\n",
    "#     def palindromePairs(self, words: List[str]) -> List[List[int]]:\n",
    "#         def is_palindrome(word):\n",
    "#             return word==word[::-1]  # 切片快于循环\n",
    "\n",
    "#         n = len(words)\n",
    "#         ans = []\n",
    "#         worddict = {word:i for i,word in enumerate(words)}\n",
    "#         for i,word in enumerate(words):\n",
    "#             m = len(word)\n",
    "#             for k in range(m+1):\n",
    "#                 prefix,suffix = word[:k][::-1],word[m-k:][::-1]\n",
    "#                 if prefix in worddict and i!=worddict[prefix] and is_palindrome(word[k:]):\n",
    "#                     ans.append([i,worddict[prefix]])\n",
    "#                 if k<m and suffix in worddict and i!=worddict[suffix] and is_palindrome(word[:m-k]):  # k<m避免镜像单词导致重复\n",
    "#                     ans.append([worddict[suffix],i])\n",
    "#         return ans\n",
    "\n",
    "# Trie树\n",
    "# class Solution:\n",
    "#     def palindromePairs(self, words: List[str]) -> List[List[int]]:\n",
    "#         def insert(word,i):\n",
    "#             node = trie\n",
    "#             for c in word:\n",
    "#                 node = node.setdefault(c,{})\n",
    "#             node['#'] = i\n",
    "        \n",
    "#         def is_palindrome(word,l,r):\n",
    "#             n = r-l+1\n",
    "#             return n<=1 or all(word[l+i]==word[l+n-i-1] for i in range(n//2))\n",
    "        \n",
    "#         def search(word,l,r):\n",
    "#             node = trie\n",
    "#             word = word[l:r+1][::-1]  # 不切片，采用下标访问会超时\n",
    "#             for c in word:\n",
    "#                 if c in node:\n",
    "#                     node = node[c]\n",
    "#                 else:\n",
    "#                     return -1\n",
    "#             return node.get('#',-1)\n",
    "\n",
    "#         n = len(words)\n",
    "#         ans = []\n",
    "#         trie = {}\n",
    "#         for i,word in enumerate(words):\n",
    "#             insert(word,i)\n",
    "#         for i,word in enumerate(words):\n",
    "#             m = len(word)\n",
    "#             for k in range(m+1):\n",
    "#                 preid,sufid = search(word,0,k-1),search(word,m-k,m-1)\n",
    "#                 if preid!=-1 and i!=preid and is_palindrome(word,k,m-1):\n",
    "#                     ans.append([i,preid])\n",
    "#                 if k<m and sufid!=-1 and i!=sufid and is_palindrome(word,0,m-k-1):  # k<m避免镜像单词导致重复\n",
    "#                     ans.append([sufid,i])\n",
    "#         return ans\n",
    "\n",
    "# class Solution:\n",
    "#     def palindromePairs(self, words: List[str]) -> List[List[int]]:\n",
    "#         def insert(trie,word,i):\n",
    "#             node = trie\n",
    "#             for c in word:\n",
    "#                 node = node.setdefault(c,{})\n",
    "#             node['#'] = i\n",
    "\n",
    "#         n = len(words)\n",
    "#         ans = []\n",
    "#         prefix,suffix,word2idx = {},{},{}\n",
    "#         for i,word in enumerate(words):\n",
    "#             insert(prefix,word,i)\n",
    "#             insert(suffix,word[::-1],i)\n",
    "#             word2idx[word] = i\n",
    "#         for i,word in enumerate(words):\n",
    "#             node = prefix\n",
    "#             for c in reversed(word):\n",
    "#                 if '#' in node:\n",
    "#                     j = node['#']\n",
    "#                     concat_word = words[j]+word\n",
    "#                     if i!=j and concat_word==concat_word[::-1]:\n",
    "#                         ans.append([j,i])\n",
    "#                 if c in node:\n",
    "#                     node = node[c]\n",
    "#                 else:\n",
    "#                     break\n",
    "#             node = suffix\n",
    "#             for c in word:\n",
    "#                 if '#' in node:\n",
    "#                     j = node['#']\n",
    "#                     concat_word = word+words[j]\n",
    "#                     if i!=j and concat_word==concat_word[::-1]:\n",
    "#                         ans.append([i,j])\n",
    "#                 if c in node:\n",
    "#                     node = node[c]\n",
    "#                 else:\n",
    "#                     break\n",
    "#             revword = word[::-1]\n",
    "#             if revword in word2idx:\n",
    "#                 j = word2idx[revword]\n",
    "#                 if i!=j:\n",
    "#                     ans.append([i,j])\n",
    "#         return ans\n",
    "\n",
    "# Trie树\n",
    "class Solution:\n",
    "    def palindromePairs(self, words: List[str]) -> List[List[int]]:\n",
    "        def insert(word,i):\n",
    "            node = trie\n",
    "            for c in word:\n",
    "                node = node.setdefault(c,{})\n",
    "            node['#'] = i\n",
    "        \n",
    "        def is_palindrome(word,l,r):\n",
    "            n = r-l+1\n",
    "            return n<=1 or all(word[l+i]==word[l+n-i-1] for i in range(n//2))\n",
    "\n",
    "        def search(word,l,r):\n",
    "            node = trie\n",
    "            for i in reversed(range(l,r+1)):\n",
    "                if word[i] in node:\n",
    "                    node = node[word[i]]\n",
    "                else:\n",
    "                    return -1\n",
    "            return node.get('#',-1)\n",
    "        \n",
    "        def search(word,l,r):\n",
    "            node = trie\n",
    "            word = word[l:r+1][::-1]  # 不切片，采用下标访问会超时\n",
    "            for c in word:\n",
    "                if c in node:\n",
    "                    node = node[c]\n",
    "                else:\n",
    "                    return -1\n",
    "            return node.get('#',-1)\n",
    "\n",
    "        n = len(words)\n",
    "        ans = []\n",
    "        trie = {}\n",
    "        for i,word in enumerate(words):\n",
    "            insert(word,i)\n",
    "        for i,word in enumerate(words):\n",
    "            m = len(word)\n",
    "            for k in range(m+1):\n",
    "                preid,sufid = search(word,0,k-1),search(word,m-k,m-1)\n",
    "                if preid!=-1 and i!=preid and is_palindrome(word,k,m-1):\n",
    "                    ans.append([i,preid])\n",
    "                if k<m and sufid!=-1 and i!=sufid and is_palindrome(word,0,m-k-1):  # k<m避免镜像单词导致重复\n",
    "                    ans.append([sufid,i])\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def palindromePairs(self, words: List[str]) -> List[List[int]]:\n",
    "\n",
    "        root = {'$':[],'#':[]}\n",
    "\n",
    "        def check(s,index):\n",
    "            l = index \n",
    "            h = len(s)-1\n",
    "            while l<h:\n",
    "                if s[l]!=s[h]:\n",
    "                    return False\n",
    "                l+=1\n",
    "                h-=1\n",
    "            return True\n",
    "\n",
    "\n",
    "        def add(l,index):\n",
    "            n = root\n",
    "            i = 0\n",
    "            if check(l,i):\n",
    "                if i>=len(l):\n",
    "                    n['#'].append(index)\n",
    "                else:\n",
    "                    n['$'].append(index)\n",
    "            for c in l:\n",
    "                if c not in n:\n",
    "                    n[c]={}\n",
    "                n = n[c]\n",
    "                i+=1\n",
    "                if check(l,i):\n",
    "                    if i>=len(l):\n",
    "                        if '#' not in n:\n",
    "                            n['#']=[]\n",
    "                        n['#'].append(index)\n",
    "                    else:\n",
    "                        if '$' not in n:\n",
    "                            n['$']=[]\n",
    "                        n['$'].append(index)\n",
    "\n",
    "\n",
    "        def search(l,index):\n",
    "            n = root \n",
    "            i = 0\n",
    "            res = []\n",
    "            while n:\n",
    "                if i>=len(l):\n",
    "                    if '$' in n and  n['$']:\n",
    "                        if check(l,i):\n",
    "                            res.extend([[k,index] for k in n['$']])\n",
    "                    if '#' in n and  n['#']:\n",
    "                        if check(l,i):\n",
    "                            res.extend([[k,index] for k in n['#'] if k!=index])\n",
    "                    break\n",
    "                else:\n",
    "                    if '#' in n and n['#']:\n",
    "                        if check(l,i):\n",
    "                            res.extend([[k,index] for k in n['#']])\n",
    "                    if l[i] not in n:\n",
    "                        break\n",
    "                    n = n[l[i]]\n",
    "                    i+=1\n",
    "            return res \n",
    "\n",
    "        res = []\n",
    "\n",
    "        for idx,w in enumerate(words):\n",
    "            add(w,idx)\n",
    "\n",
    "        for idx,w in enumerate(words):\n",
    "            res.extend(search(w[-1::-1],idx))\n",
    "\n",
    "        return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Trie:\n",
    "    def __init__(self):\n",
    "        self.children={}\n",
    "        self.index=-1\n",
    "class Solution:\n",
    "    def palindromePairs(self, words: List[str]) -> List[List[int]]:\n",
    "        root=Trie()\n",
    "        n=len(words)\n",
    "        for i in range(n):\n",
    "            node=root\n",
    "            for s in words[i]:\n",
    "                if not s in node.children:\n",
    "                    node.children[s]=Trie()\n",
    "                node=node.children[s]\n",
    "            node.index=i\n",
    "        def search(left,right):\n",
    "            node=root\n",
    "            for i in range(right,left-1,-1):\n",
    "                if not word[i] in node.children:\n",
    "                    return -1\n",
    "                node=node.children[word[i]]\n",
    "            return node.index\n",
    "        def ispa(left,right):\n",
    "            left_index=left\n",
    "            right_index=right\n",
    "            while left_index < right_index:\n",
    "                if not word[left_index]==word[right_index]:\n",
    "                    return False\n",
    "                left_index+=1\n",
    "                right_index-=1\n",
    "            return True\n",
    "        ans=[]\n",
    "        for i in range(n):\n",
    "            word=words[i]\n",
    "            m=len(word)\n",
    "            for j in range(m+1):\n",
    "                if j and ispa(0,j-1):\n",
    "                    k=search(j,m-1)\n",
    "                    if k>-1 and k!= i:\n",
    "                        ans.append([k,i])\n",
    "                if ispa(j,m-1):\n",
    "                    k=search(0,j-1)\n",
    "                    if k>-1 and k!= i:\n",
    "                        ans.append([i,k])\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# 暴力（超时）\n",
    "# class Solution:\n",
    "#     def palindromePairs(self, words: List[str]) -> List[List[int]]:\n",
    "#         n = len(words)\n",
    "#         ans = []\n",
    "#         for i in range(n):\n",
    "#             for j in range(n):\n",
    "#                 if i!=j:\n",
    "#                     word = words[i]+words[j]\n",
    "#                     if word==word[::-1]:\n",
    "#                         ans.append([i,j])\n",
    "#         return ans\n",
    "\n",
    "# 哈希表\n",
    "# class Solution:\n",
    "#     def palindromePairs(self, words: List[str]) -> List[List[int]]:\n",
    "#         def is_palindrome(word,l,r):\n",
    "#             n = r-l+1\n",
    "#             return n<=1 or all(word[l+i]==word[l+n-i-1] for i in range(n//2))\n",
    "\n",
    "#         n = len(words)\n",
    "#         ans = []\n",
    "#         worddict = {word:i for i,word in enumerate(words)}\n",
    "#         for i,word in enumerate(words):\n",
    "#             m = len(word)\n",
    "#             for k in range(m+1):\n",
    "#                 prefix,suffix = word[:k][::-1],word[m-k:][::-1]\n",
    "#                 if prefix in worddict and i!=worddict[prefix] and is_palindrome(word,k,m-1):\n",
    "#                     ans.append([i,worddict[prefix]])\n",
    "#                 if k<m and suffix in worddict and i!=worddict[suffix] and is_palindrome(word,0,m-k-1):  # k<m避免镜像单词导致重复\n",
    "#                     ans.append([worddict[suffix],i])\n",
    "#         return ans\n",
    "\n",
    "# class Solution:\n",
    "#     def palindromePairs(self, words: List[str]) -> List[List[int]]:\n",
    "#         def is_palindrome(word):\n",
    "#             return word==word[::-1]  # 切片快于循环\n",
    "\n",
    "#         n = len(words)\n",
    "#         ans = []\n",
    "#         worddict = {word:i for i,word in enumerate(words)}\n",
    "#         for i,word in enumerate(words):\n",
    "#             m = len(word)\n",
    "#             for k in range(m+1):\n",
    "#                 prefix,suffix = word[:k][::-1],word[m-k:][::-1]\n",
    "#                 if prefix in worddict and i!=worddict[prefix] and is_palindrome(word[k:]):\n",
    "#                     ans.append([i,worddict[prefix]])\n",
    "#                 if k<m and suffix in worddict and i!=worddict[suffix] and is_palindrome(word[:m-k]):  # k<m避免镜像单词导致重复\n",
    "#                     ans.append([worddict[suffix],i])\n",
    "#         return ans\n",
    "\n",
    "# Trie树\n",
    "# class Solution:\n",
    "#     def palindromePairs(self, words: List[str]) -> List[List[int]]:\n",
    "#         def insert(word,i):\n",
    "#             node = trie\n",
    "#             for c in word:\n",
    "#                 node = node.setdefault(c,{})\n",
    "#             node['#'] = i\n",
    "        \n",
    "#         def is_palindrome(word,l,r):\n",
    "#             n = r-l+1\n",
    "#             return n<=1 or all(word[l+i]==word[l+n-i-1] for i in range(n//2))\n",
    "        \n",
    "#         def search(word,l,r):\n",
    "#             node = trie\n",
    "#             word = word[l:r+1][::-1]  # 不切片，采用下标访问会超时\n",
    "#             for c in word:\n",
    "#                 if c in node:\n",
    "#                     node = node[c]\n",
    "#                 else:\n",
    "#                     return -1\n",
    "#             return node.get('#',-1)\n",
    "\n",
    "#         n = len(words)\n",
    "#         ans = []\n",
    "#         trie = {}\n",
    "#         for i,word in enumerate(words):\n",
    "#             insert(word,i)\n",
    "#         for i,word in enumerate(words):\n",
    "#             m = len(word)\n",
    "#             for k in range(m+1):\n",
    "#                 preid,sufid = search(word,0,k-1),search(word,m-k,m-1)\n",
    "#                 if preid!=-1 and i!=preid and is_palindrome(word,k,m-1):\n",
    "#                     ans.append([i,preid])\n",
    "#                 if k<m and sufid!=-1 and i!=sufid and is_palindrome(word,0,m-k-1):  # k<m避免镜像单词导致重复\n",
    "#                     ans.append([sufid,i])\n",
    "#         return ans\n",
    "\n",
    "# class Solution:\n",
    "#     def palindromePairs(self, words: List[str]) -> List[List[int]]:\n",
    "#         def insert(trie,word,i):\n",
    "#             node = trie\n",
    "#             for c in word:\n",
    "#                 node = node.setdefault(c,{})\n",
    "#             node['#'] = i\n",
    "\n",
    "#         def is_palindrome(word):\n",
    "#             return word==word[::-1]  # 切片快于循环\n",
    "\n",
    "#         n = len(words)\n",
    "#         ans = []\n",
    "#         prefix,suffix,word2idx = {},{},{}\n",
    "#         for i,word in enumerate(words):\n",
    "#             insert(prefix,word,i)\n",
    "#             insert(suffix,word[::-1],i)\n",
    "#             word2idx[word] = i\n",
    "#         for i,word in enumerate(words):\n",
    "#             node = prefix\n",
    "#             for c in reversed(word):\n",
    "#                 if '#' in node:\n",
    "#                     j = node['#']\n",
    "#                     if i!=j and is_palindrome(word[:len(word)-len(words[j])]):\n",
    "#                         ans.append([j,i])\n",
    "#                 if c in node:\n",
    "#                     node = node[c]\n",
    "#                 else:\n",
    "#                     break\n",
    "#             node = suffix\n",
    "#             for c in word:\n",
    "#                 if '#' in node:\n",
    "#                     j = node['#']\n",
    "#                     if i!=j and is_palindrome(word[len(words[j]):]):\n",
    "#                         ans.append([i,j])\n",
    "#                 if c in node:\n",
    "#                     node = node[c]\n",
    "#                 else:\n",
    "#                     break\n",
    "#             revword = word[::-1]\n",
    "#             if revword in word2idx:\n",
    "#                 j = word2idx[revword]\n",
    "#                 if i!=j:\n",
    "#                     ans.append([i,j])\n",
    "#         return ans\n",
    "\n",
    "# Trie树+Manacher算法\n",
    "class Solution:\n",
    "    def palindromePairs(self, words: List[str]) -> List[List[int]]:\n",
    "        def manacher(word):\n",
    "            prefix = [False]*(len(word)+1)\n",
    "            suffix = [False]*(len(word)+1)\n",
    "            s = '#'+'#'.join(word)+'#'\n",
    "            n = len(s)\n",
    "            radius = [1]*n\n",
    "            r_max,i_max = 0,0\n",
    "            for i in range(n):\n",
    "                if i>=r_max:\n",
    "                    r_max = i_max = i\n",
    "                radius[i] = min(radius[2*i_max-i],r_max-i+1)\n",
    "                while i-radius[i]>=0 and i+radius[i]<n and s[i+radius[i]]==s[i-radius[i]]:\n",
    "                    radius[i] += 1\n",
    "                if i+radius[i]-1>r_max:\n",
    "                    r_max = i+radius[i]-1\n",
    "                    i_max = i\n",
    "                if i-radius[i]+1 == 0:\n",
    "                    prefix[radius[i]-1] = True\n",
    "                if i+radius[i] == n:\n",
    "                    suffix[radius[i]-1] = True\n",
    "            return prefix,suffix\n",
    "\n",
    "        def insert(trie,word,i):\n",
    "            node = trie\n",
    "            for c in word:\n",
    "                node = node.setdefault(c,{})\n",
    "            node['#'] = i\n",
    "        \n",
    "        def query(trie,word):\n",
    "            node = trie\n",
    "            ans = []\n",
    "            for c in word:\n",
    "                if '#' in node:\n",
    "                    ans.append(node['#'])\n",
    "                if c not in node:\n",
    "                    return ans\n",
    "                node = node[c]\n",
    "            if '#' in node:\n",
    "                ans.append(node['#'])\n",
    "            return ans\n",
    "\n",
    "        n = len(words)\n",
    "        ans = []\n",
    "        prefix,suffix = {},{}\n",
    "        prefix_palindrome,suffix_palindrome = [None]*n,[None]*n\n",
    "        for i,word in enumerate(words):\n",
    "            insert(prefix,word,i)\n",
    "            insert(suffix,word[::-1],i)\n",
    "            prefix_palindrome[i],suffix_palindrome[i] = manacher(word)\n",
    "        for i,word in enumerate(words):\n",
    "            preifx_id = query(prefix,word[::-1])\n",
    "            suffix_id = query(suffix,word)\n",
    "            for j in preifx_id:\n",
    "                if i!=j and prefix_palindrome[i][len(word)-len(words[j])]:\n",
    "                    ans.append([j,i])\n",
    "            for j in suffix_id:\n",
    "                if len(word)!=len(words[j]) and i!=j and suffix_palindrome[i][len(word)-len(words[j])]:\n",
    "                    ans.append([i,j])\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Trie:\n",
    "\n",
    "    def __init__(self):\n",
    "        self.lookup = {}\n",
    "\n",
    "\n",
    "    def insert(self, word: str) -> None:\n",
    "        tree = self.lookup\n",
    "\n",
    "        for s in word:\n",
    "            if s not in tree:\n",
    "                tree[s] = {}\n",
    "            tree = tree[s]\n",
    "        tree['#'] = '#'\n",
    "\n",
    "    def search(self, word: str) -> bool:\n",
    "        tree = self.lookup\n",
    "        for s in word:\n",
    "            if s not in tree:\n",
    "                return False\n",
    "            tree = tree[s]\n",
    "        if '#' in tree:\n",
    "            return True\n",
    "\n",
    "        else:\n",
    "            return False\n",
    "\n",
    "class Solution:\n",
    "    def get_palindrome_parts(self,str):\n",
    "        pre,suf = [],[]\n",
    "        lenstr = len(str)\n",
    "\n",
    "        for i in range(0,lenstr + 1):\n",
    "            if str[:i] == str[:i][::-1]:\n",
    "                pre.append(str[i:][::-1])\n",
    "\n",
    "            if str[i:] == str[i:][::-1]:\n",
    "                suf.append(str[:i][::-1])\n",
    "\n",
    "        return pre, suf\n",
    "\n",
    "\n",
    "    def palindromePairs(self, words):\n",
    "        tree = Trie()\n",
    "        for w in words:\n",
    "            tree.insert(w)\n",
    "        dataset = {w:i for i,w in enumerate(words)}\n",
    "        res = []\n",
    "\n",
    "        for index, word in enumerate(words):\n",
    "            pre, suf = self.get_palindrome_parts(word)\n",
    "\n",
    "            for p in pre:\n",
    "                if p in dataset and index != dataset[p] and p[::-1] != word:\n",
    "                    res.append([dataset[p],index])\n",
    "            \n",
    "            for s in suf:\n",
    "                if s in dataset  and index != dataset[s]:\n",
    "                    res.append([index, dataset[s]])\n",
    "        \n",
    "        return res\n",
    "\n",
    "\n",
    "\n",
    "      "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Node:\n",
    "    def __init__(self, val):\n",
    "        self.val = val\n",
    "        self.neighbors = {}\n",
    "        self.flag = -1\n",
    "\n",
    "\n",
    "class Solution(object):\n",
    "    def palindromePairs(self, words):\n",
    "        \"\"\"\n",
    "        :type words: List[str]\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        tree = Node('#')\n",
    "        out = []\n",
    "        for k, word in enumerate(words):\n",
    "            node = tree\n",
    "            for i in range(len(word)):\n",
    "                if word[i] not in node.neighbors:\n",
    "                    new_node = Node(word[i])\n",
    "                    node.neighbors[word[i]] = new_node\n",
    "                    node = new_node\n",
    "                else:\n",
    "                    node = node.neighbors[word[i]]\n",
    "            node.flag = k\n",
    "\n",
    "        def search(node, m, k):\n",
    "            if node.flag >= 0:\n",
    "                new_word = words[node.flag][m:]\n",
    "                if new_word == new_word[::-1]:\n",
    "                    out.append([node.flag, k])\n",
    "            for next_node in node.neighbors:\n",
    "                search(node.neighbors[next_node], m, k)\n",
    "\n",
    "        for k, word in enumerate(words):\n",
    "            m = len(word)\n",
    "            node = tree\n",
    "            i = 0\n",
    "            while i < m:\n",
    "                if node.flag >= 0:\n",
    "                    new_word = word[: m - i]\n",
    "                    if new_word == new_word[::-1]:\n",
    "                        out.append([node.flag, k])\n",
    "                if word[m - 1 - i] in node.neighbors:\n",
    "                    node = node.neighbors[word[m - 1 - i]]\n",
    "                    i += 1\n",
    "                else:\n",
    "                    break\n",
    "            if i == m:\n",
    "                if node.flag >= 0 and k != node.flag:\n",
    "                    out.append([node.flag, k])\n",
    "                for next_node in node.neighbors:\n",
    "                    search(node.neighbors[next_node], m, k)\n",
    "        return out"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Trie:\n",
    "    def __init__(self):\n",
    "        self.children = [None] * 26\n",
    "        self.isEnd = -1\n",
    "    \n",
    "    def insert(self, w: str, i: int) -> None:\n",
    "        p = self\n",
    "        for ch in w:\n",
    "            idx = ord(ch) - ord('a')\n",
    "            if not p.children[idx]:\n",
    "                p.children[idx] = Trie()\n",
    "            p = p.children[idx]\n",
    "        p.isEnd = i\n",
    "    \n",
    "    def search(self, w: str) -> List[int]:\n",
    "        res = []\n",
    "        if self.isEnd != -1 and w == w[::-1]:\n",
    "            res.append(self.isEnd)\n",
    "        p = self\n",
    "        for j, ch in enumerate(w):\n",
    "            idx = ord(ch) - ord('a')\n",
    "            if not p.children[idx]:\n",
    "                return res\n",
    "            p = p.children[idx]\n",
    "            if p.isEnd != -1 and w[j+1:] == w[j+1:][::-1]:\n",
    "                res.append(p.isEnd)\n",
    "        return res\n",
    "\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def palindromePairs(self, words: List[str]) -> List[List[int]]:\n",
    "        res = []\n",
    "        words = [(x, i) for i, x in enumerate(words)]\n",
    "        words.sort(key=lambda x: len(x[0]))\n",
    "\n",
    "        trie = Trie()\n",
    "        for w, i in words:\n",
    "            ans = trie.search(w)\n",
    "            if len(ans) > 0:\n",
    "                res += [[i, j] for j in ans]\n",
    "            trie.insert(w[::-1], i)\n",
    "\n",
    "        trie = Trie()\n",
    "        for w, i in words:\n",
    "            ans = trie.search(w[::-1])\n",
    "            if len(ans) > 0:\n",
    "                res += [[j, i] for j in ans]\n",
    "            trie.insert(w, i)\n",
    "        return res\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class TrieNode:\n",
    "    def __init__(self):\n",
    "        self.index = -1 # represent the index of the word for this search\n",
    "        self.children = [None]*26\n",
    "class Trie:\n",
    "    def __init__(self):\n",
    "        self.root = TrieNode()\n",
    "    def insert(self, w, index):\n",
    "        curNode = self.root\n",
    "        for c in w:\n",
    "            cindex = ord(c)-ord('a')\n",
    "            if not curNode.children[cindex]:\n",
    "                curNode.children[cindex] = TrieNode()\n",
    "            curNode = curNode.children[cindex]\n",
    "        curNode.index = index\n",
    "    def search(self, c, node):\n",
    "        curNode = node\n",
    "        cindex = ord(c)-ord('a')\n",
    "        if not curNode or not curNode.children[cindex]:\n",
    "            return (False, None)\n",
    "        curNode = curNode.children[cindex]\n",
    "        return (curNode.index != -1, curNode)\n",
    "\n",
    "class Solution:\n",
    "    def isPalindrome(self, w, l, r):\n",
    "        # print(w, l, r)\n",
    "        if l >= r: return True\n",
    "        if w[l] != w[r]: return False\n",
    "        return self.isPalindrome(w, l+1, r-1)\n",
    "    def palindromePairs(self, words: List[str]) -> List[List[int]]:\n",
    "        dictTree = Trie()\n",
    "        ret = []\n",
    "        for i, w in enumerate(words):\n",
    "            dictTree.insert(w[::-1], i)\n",
    "            if w == '': dictTree.root.index = i\n",
    "        for i, w in enumerate(words):\n",
    "            curNode = dictTree.root\n",
    "            wl = len(w)\n",
    "            for j, c in enumerate(w):\n",
    "                result, curNode = dictTree.search(c, curNode)\n",
    "                # print(w, c, result)\n",
    "                if not curNode: break\n",
    "                if result and curNode.index != i and self.isPalindrome(w, j+1, wl-1):\n",
    "                    ret.append([i, curNode.index])\n",
    "            if w != '' and dictTree.root.index != -1 and self.isPalindrome(w, 0, wl-1):\n",
    "                ret.append([i, dictTree.root.index])\n",
    "                ret.append([dictTree.root.index, i])\n",
    "        dictTree = Trie()\n",
    "        for i, w in enumerate(words):\n",
    "            dictTree.insert(w, i)\n",
    "        for i, w in enumerate(words):\n",
    "            curNode = dictTree.root\n",
    "            wl = len(w)\n",
    "            for j, c in enumerate(w[::-1]):\n",
    "                # print(w, c, j)\n",
    "                result, curNode = dictTree.search(c, curNode)\n",
    "                # print(w, c, result)\n",
    "                if not curNode: break\n",
    "                if result and curNode.index != i and self.isPalindrome(w, 0, wl-j-2):\n",
    "                    if len(words[curNode.index]) != len(w):\n",
    "                        ret.append([curNode.index, i])\n",
    "        return ret \n",
    "\n",
    "\n",
    "\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Trie:\n",
    "    def __init__(self):\n",
    "        self.dct = dict()\n",
    "\n",
    "    def add(self, word, i):\n",
    "        cur = self.dct\n",
    "        for va in word:\n",
    "            if va not in cur:\n",
    "                cur[va] = dict()\n",
    "            cur = cur[va]\n",
    "        cur['isEnd'] = i\n",
    "        return\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def palindromePairs(self, words):\n",
    "        \n",
    "        # 按照长度进行排序\n",
    "        n = len(words)\n",
    "        for i in range(n):\n",
    "            words[i] = [words[i], i]\n",
    "        words.sort(key=lambda x: [len(x[0]), x[0]])\n",
    "        \n",
    "        # 正反字典树\n",
    "        trie = Trie()\n",
    "        trie_rev = Trie()\n",
    "\n",
    "        def check(l, r):\n",
    "            while l < r:\n",
    "                if word[r] == word[l]:\n",
    "                    l += 1\n",
    "                    r -= 1\n",
    "                else:\n",
    "                    break\n",
    "            return l >= r\n",
    "\n",
    "        res = []\n",
    "        for word, i in words:\n",
    "            m = len(word)\n",
    "            # 当前字符在后面\n",
    "            cur = trie.dct\n",
    "            j = m-1\n",
    "            search = True\n",
    "            while j >= 0:\n",
    "                if 'isEnd' in cur and check(0, j):\n",
    "                    res.append([cur['isEnd'], i])\n",
    "                if word[j] in cur:\n",
    "                    cur = cur[word[j]]\n",
    "                    j -= 1\n",
    "                else:\n",
    "                    search = False\n",
    "                    break\n",
    "            if search and 'isEnd' in cur and check(0, j):\n",
    "                res.append([cur['isEnd'], i])\n",
    "            trie.add(word, i)\n",
    "\n",
    "            # 当前字符在前面\n",
    "            cur = trie_rev.dct\n",
    "            j = 0\n",
    "            search = True\n",
    "            while j <= m-1:\n",
    "                if 'isEnd' in cur and check(j, m-1):\n",
    "                    res.append([i, cur['isEnd']])\n",
    "                if word[j] in cur:\n",
    "                    cur = cur[word[j]]\n",
    "                    j += 1\n",
    "                else:\n",
    "                    search = False\n",
    "                    break\n",
    "            if search and 'isEnd' in cur and check(j, m-1):\n",
    "                res.append([i, cur['isEnd']])\n",
    "            trie_rev.add(word[::-1], i)\n",
    "        return res\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class TrieNode:\n",
    "    def __init__(self):\n",
    "        self.palindrome_suffixes = []\n",
    "        self.children = [None] * 26\n",
    "        self.word_id = -1\n",
    "\n",
    "class Solution:\n",
    "    def palindromePairs(self, words: List[str]) -> List[List[int]]:\n",
    "        def insert(root, word, word_id):\n",
    "            for i in range(len(word) - 1, -1, -1):\n",
    "                c = ord(word[i]) - ord('a')\n",
    "                if not root.children[c]:\n",
    "                    root.children[c] = TrieNode()\n",
    "                if is_palindrome(word, 0, i):\n",
    "                    root.palindrome_suffixes.append(word_id)\n",
    "                root = root.children[c]\n",
    "            root.word_id = word_id\n",
    "            root.palindrome_suffixes.append(word_id)\n",
    "\n",
    "        def search(root, word, word_id, result):\n",
    "            for i, c in enumerate(word):\n",
    "                if root.word_id >= 0 and root.word_id != word_id and is_palindrome(word, i, len(word) - 1):\n",
    "                    result.append([word_id, root.word_id])\n",
    "                root = root.children[ord(c) - ord('a')]\n",
    "                if not root:\n",
    "                    return\n",
    "            for j in root.palindrome_suffixes:\n",
    "                if j != word_id:\n",
    "                    result.append([word_id, j])\n",
    "\n",
    "        def is_palindrome(word, left, right):\n",
    "            while left < right:\n",
    "                if word[left] != word[right]:\n",
    "                    return False\n",
    "                left += 1\n",
    "                right -= 1\n",
    "            return True\n",
    "\n",
    "        root = TrieNode()\n",
    "        for i, word in enumerate(words):\n",
    "            insert(root, word, i)\n",
    "\n",
    "        result = []\n",
    "        for i, word in enumerate(words):\n",
    "            search(root, word, i, result)\n",
    "\n",
    "        return result\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumTime(self, n: int, relations: List[List[int]], time: List[int]) -> int:\n",
    "        indegs = [set() for _ in range(n)]\n",
    "        for prev_course, next_course in relations:\n",
    "            indegs[prev_course - 1].add(next_course - 1)\n",
    "        @cache\n",
    "        def memorysearch(course: int) -> int:\n",
    "            cost = 0\n",
    "            for prev in indegs[course]:\n",
    "                cost = max(cost, memorysearch(prev))\n",
    "            cost += time[course]\n",
    "            return cost\n",
    "\n",
    "        res = 0\n",
    "        for i in range(n):\n",
    "            res = max(res, memorysearch(i))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def partitionDisjoint(self, A: List[int]) -> int:\n",
    "        n = len(A)\n",
    "\n",
    "        self.tree = [None] * (n * 4 + 1)\n",
    "\n",
    "        def build_tree(tree_index, left, right):\n",
    "            if left == right:\n",
    "                self.tree[tree_index] = (A[left], A[left])\n",
    "                return self.tree[tree_index]\n",
    "            else:\n",
    "                mid = left + (right - left) // 2\n",
    "                left_c_id = tree_index * 2\n",
    "                right_c_id = left_c_id + 1\n",
    "                lm = build_tree(left_c_id, left, mid)\n",
    "                rm = build_tree(right_c_id, mid + 1, right)\n",
    "                self.tree[tree_index] = min(lm[0], rm[0]), max(lm[1], rm[1])\n",
    "                return self.tree[tree_index] \n",
    "        \n",
    "        def search(tree_index, l, r, ql, qr):\n",
    "            if l == ql and r == qr:\n",
    "                return self.tree[tree_index]\n",
    "            \n",
    "            mid = l + (r - l) // 2\n",
    "            left_c_id = tree_index * 2\n",
    "            right_c_id = left_c_id + 1\n",
    "\n",
    "            if qr <= mid:\n",
    "                return search(left_c_id, l, mid, ql, qr)\n",
    "            elif ql > mid:\n",
    "                return search(right_c_id, mid + 1, r, ql, qr)\n",
    "            else:\n",
    "                lm = search(left_c_id, l, mid, ql, mid)\n",
    "                rm = search(right_c_id, mid + 1, r, mid + 1, qr)\n",
    "                return min(lm[0], rm[0]), max(lm[1], rm[1])\n",
    "\n",
    "        build_tree(1, 0, n - 1)\n",
    "\n",
    "        for i in range(1, n):\n",
    "            left_max = search(1, 0, n - 1, 0, i - 1)[1]\n",
    "            right_min = search(1, 0, n - 1, i, n - 1)[0]\n",
    "            # print(left_max, right_min)\n",
    "            if left_max <= right_min:\n",
    "                return i"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumDifference(self, nums: List[int]) -> int:\n",
    "        n = len(nums) // 2\n",
    "        s = sum(nums)\n",
    "        L = nums[:n]\n",
    "        pre_cnt = defaultdict(list)\n",
    "\n",
    "        def cal(x, Li):\n",
    "            res = 0\n",
    "            for i in range(n):\n",
    "                if (x >> i) & 1:\n",
    "                    res += Li[i]\n",
    "            return res \n",
    "\n",
    "        def f(x):\n",
    "            return abs(s - 2 * x)\n",
    "\n",
    "        ans = inf \n",
    "        for i in range(1 << n):\n",
    "            pre_cnt[i.bit_count()].append(cal(i, L))\n",
    "        for k, v in pre_cnt.items():\n",
    "            pre_cnt[k] = [-inf] + sorted(set(v)) + [inf]\n",
    "        aft = nums[n:]\n",
    "        for i in range(1 << n):\n",
    "            tmp = cal(i, aft)\n",
    "            search = pre_cnt[n - i.bit_count()]            \n",
    "            ln = len(search)\n",
    "            if not ln:\n",
    "                continue \n",
    "            idx = bisect_left(search, s / 2 - tmp)\n",
    "            # if idx == ln:\n",
    "            #     ans = min(ans, f(tmp + search[-1]))\n",
    "            # elif search[idx] == s / 2 - tmp:\n",
    "            #     return 0\n",
    "            # elif idx == 0:\n",
    "            #     ans = min(ans, f(tmp + search[0]))\n",
    "            # else:\n",
    "            ans = min(ans, f(tmp + search[idx - 1]), f(tmp + search[idx]))\n",
    "            if ans == s % 2:\n",
    "                return s % 2\n",
    "        return ans "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minimumDifference(self, nums: List[int]) -> int:\n",
    "        n = len(nums) // 2\n",
    "        s = sum(nums)\n",
    "        L = nums[:n]\n",
    "        pre_cnt = defaultdict(list)\n",
    "\n",
    "        def cal(x, Li):\n",
    "            res = 0\n",
    "            for i in range(n):\n",
    "                if (x >> i) & 1:\n",
    "                    res += Li[i]\n",
    "            return res \n",
    "\n",
    "        def f(x):\n",
    "            return abs(s - 2 * x)\n",
    "\n",
    "        ans = inf \n",
    "        for i in range(1 << n):\n",
    "            pre_cnt[i.bit_count()].append(cal(i, L))\n",
    "        for k, v in pre_cnt.items():\n",
    "            pre_cnt[k] = sorted(set(v))\n",
    "        aft = nums[n:]\n",
    "        for i in range(1 << n):\n",
    "            tmp = cal(i, aft)\n",
    "            search = pre_cnt[n - i.bit_count()]            \n",
    "            ln = len(search)\n",
    "            if not ln:\n",
    "                continue \n",
    "            idx = bisect_left(search, s / 2 - tmp)\n",
    "            if idx == ln:\n",
    "                ans = min(ans, f(tmp + search[-1]))\n",
    "            elif search[idx] == s / 2 - tmp:\n",
    "                return 0\n",
    "            elif idx == 0:\n",
    "                ans = min(ans, f(tmp + search[0]))\n",
    "            else:\n",
    "                ans = min(ans, f(tmp + search[idx - 1]), f(tmp + search[idx]))\n",
    "        return ans "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def partition(self, head, x):\n",
    "        \"\"\"\n",
    "        :type head: ListNode\n",
    "        :type x: int\n",
    "        :rtype: ListNode\n",
    "        \"\"\"\n",
    "        lowList=[]\n",
    "        upList=[]\n",
    "\n",
    "        def searchList(listNode, x):\n",
    "            if listNode:\n",
    "                curVal = listNode.val\n",
    "                if curVal < x:\n",
    "                    #print(curVal)\n",
    "                    lowList.append(curVal)\n",
    "                else :\n",
    "                    upList.append(curVal)\n",
    "                searchList(listNode.next, x)\n",
    "\n",
    "        def replaceList(head, level=0):\n",
    "            if head:\n",
    "                head.val = lowList[level]\n",
    "                replaceList(head.next, level+1)                    \n",
    "        searchList(head, x)\n",
    "        lowList.extend(upList)\n",
    "        replaceList(head)\n",
    "        return head\n",
    "       # def replaceList(head, level=0):\n",
    "       #     if head:\n",
    "       #         head.val = newList[level]\n",
    "       #         replaceList(head.next, level+1)\n",
    "                \n",
    "        #replaceList(head)\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def canPartitionKSubsets(self, nums, k):\n",
    "        target, mod = divmod(sum(nums), k)\n",
    "        if mod or max(nums) > target: \n",
    "            return False\n",
    "        memo = [0] * (1 << len(nums))\n",
    "        memo[-1] = True\n",
    "        def search(used, todo):\n",
    "            if memo[used] is 0:\n",
    "                targ = (todo - 1) % target + 1\n",
    "                memo[used] = any(search(used | (1<<i), todo - num)\n",
    "                                  for i, num in enumerate(nums)\n",
    "                                  if (used >> i) & 1 == 0 and num <= targ)\n",
    "            return memo[used]      \n",
    "        return search(0, target * k)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def pathWithObstacles(self, obstacleGrid: List[List[int]]) -> List[List[int]]:\n",
    "        if obstacleGrid[0][0]==1 or obstacleGrid[-1][-1]==1:\n",
    "            return []\n",
    "\n",
    "        ans_all = list()\n",
    "        visited_list = set()\n",
    "        def search(i, j, ans):\n",
    "            if i == len(obstacleGrid)-1 and j == len(obstacleGrid[0])-1:\n",
    "                ans_all.append(ans)\n",
    "                return\n",
    "            if len(ans_all) > 0:\n",
    "                return\n",
    "            \n",
    "            visited_list.add((i, j))\n",
    "            if j+1 < len(obstacleGrid[0]) and obstacleGrid[i][j+1] != 1 and (i,j+1) not in visited_list:\n",
    "                search(i, j+1, ans+[[i, j+1]])\n",
    "            if i+1 < len(obstacleGrid) and obstacleGrid[i+1][j] != 1 and (i+1, j) not in visited_list:\n",
    "                search(i+1, j, ans+[[i+1, j]])\n",
    "\n",
    "        search(0, 0, [[0,0]])\n",
    "        \n",
    "        return ans_all[0] if len(ans_all) > 0 else []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findWhetherExistsPath(self, n: int, graph: List[List[int]], start: int, target: int) -> bool:\n",
    "        path = [set() for _ in range(n)]\n",
    "        for i, j in graph:\n",
    "            path[i].add(j)\n",
    "\n",
    "        searched = set()\n",
    "        tosearch = path[start]\n",
    "\n",
    "        while tosearch:\n",
    "            next_tosearch = set()\n",
    "            if target in tosearch:\n",
    "                return True\n",
    "            searched = searched.union(tosearch)\n",
    "            for i in tosearch:\n",
    "                for j in path[i]:\n",
    "                    if j not in searched: \n",
    "                        next_tosearch.add(j)\n",
    "            tosearch = next_tosearch\n",
    "        \n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validPalindrome(self, s: str) -> bool:\n",
    "        first=0\n",
    "        second=len(s)-1\n",
    "        while first<=second:\n",
    "            if s[first]==s[second]:\n",
    "                first+=1\n",
    "                second-=1\n",
    "            else:\n",
    "                re1=self.search(s, first+1, second)\n",
    "                if re1:\n",
    "                    return True\n",
    "                re2=self.search(s, first, second-1)\n",
    "                if re2:\n",
    "                    return True\n",
    "                else:\n",
    "                    return False\n",
    "        return True\n",
    "\n",
    "    def search(self, s, first, second):\n",
    "        while first<=second:\n",
    "            if s[first]==s[second]:\n",
    "                first+=1\n",
    "                second-=1\n",
    "            else:\n",
    "                return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxEnvelopes(self, envelopes: List[List[int]]) -> int:\n",
    "        \n",
    "        self.sorted_(envelopes)\n",
    "        print(envelopes)\n",
    "\n",
    "        lis_in2 = [i[1] for i in envelopes]\n",
    "        print(lis_in2)\n",
    "\n",
    "        return self.lengthOfLIS(lis_in2)\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "        \n",
    "    def sorted_(self, envs):\n",
    "        envs.sort()\n",
    "        # envs_r = copy.deepcopy(envs)\n",
    "        # envs_r.reverse()\n",
    "        lene = len(envs)\n",
    "\n",
    "        if lene == 1:\n",
    "            return None\n",
    "\n",
    "        st_rc = 0\n",
    "        st = 0\n",
    "\n",
    "        last_ = None\n",
    "\n",
    "        sorted_tmp = []\n",
    "\n",
    "        while st < lene:\n",
    "\n",
    "            # print(envs, sorted_tmp)\n",
    "\n",
    "            rst = lene - 1 - st\n",
    "            if envs[rst][0] == last_:\n",
    "                sorted_tmp.append(envs[rst])\n",
    "                # sorted_tmp.sort().reverse()\n",
    "            \n",
    "            else:\n",
    "                sti = 0\n",
    "                # print('st_rc', st_rc)\n",
    "                for i in range(rst + 1, st_rc + 1):\n",
    "                    # print(i, sti)\n",
    "                    envs[i] = sorted_tmp[sti]\n",
    "                    sti += 1\n",
    "\n",
    "\n",
    "                sorted_tmp = [envs[rst]]\n",
    "                st_rc = rst\n",
    "            \n",
    "            last_ = envs[rst][0]\n",
    "            \n",
    "            st += 1\n",
    "        \n",
    "        sti = 0\n",
    "        # print('st_rc', st_rc, rst)\n",
    "        for i in range(rst, st_rc + 1):\n",
    "            print(i, sti)\n",
    "            envs[i] = sorted_tmp[sti]\n",
    "            sti += 1\n",
    "                \n",
    "                \n",
    "            \n",
    "\n",
    "        \n",
    "\n",
    "        \n",
    "        \n",
    "\n",
    "\n",
    "    # def sorted_(self, inlist):\n",
    "    #     leni = len(inlist)\n",
    "\n",
    "        \n",
    "\n",
    "        \n",
    "        \n",
    "\n",
    "    \n",
    "\n",
    "    def lengthOfLIS(self, nums: List[int]) -> int:\n",
    "        # print(range(10 - 1, -1, -1))\n",
    "        # for i in range(9, -1, -1):\n",
    "        # print(i)\n",
    "\n",
    "        lenn = len(nums)\n",
    "\n",
    "        ssets = [[]]\n",
    "\n",
    "        for i in range(lenn):\n",
    "            if i == 0:\n",
    "                ssets[0].append(nums[i])\n",
    "            else:\n",
    "                self.searched(nums[i], ssets)\n",
    "\n",
    "        return len(ssets)\n",
    "\n",
    "    def searched(self, target, numlist):\n",
    "\n",
    "        left = 0\n",
    "        right = len(numlist)\n",
    "\n",
    "        if target > numlist[-1][-1]:\n",
    "            numlist.append([target])\n",
    "            return None\n",
    "\n",
    "        if target <= numlist[0][-1]:\n",
    "            numlist[0].append(target)\n",
    "            return None\n",
    "\n",
    "        # print(numlist)\n",
    "        while left < right:\n",
    "            mid = int(left + (right - left) / 2)\n",
    "\n",
    "            if numlist[mid][-1] == target:\n",
    "                numlist[mid].append(target)\n",
    "                return None\n",
    "\n",
    "            elif numlist[mid][-1] > target:\n",
    "                right = mid\n",
    "\n",
    "            elif numlist[mid][-1] < target:\n",
    "                left = mid\n",
    "\n",
    "            if left + 1 == right:\n",
    "                break\n",
    "\n",
    "        # print(left, numlist)\n",
    "        numlist[left + 1].append(target)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def equationsPossible(self, equations: 'List[str]') -> 'bool':\n",
    "        h = {}\n",
    "        def search(c):\n",
    "            while h.get(c,c) != c:\n",
    "                c = h[c]\n",
    "            return c\n",
    "        for e in equations:\n",
    "            if e[1] == \"=\":\n",
    "                if e[0] not in h:\n",
    "                    h[e[0]] = e[0]\n",
    "                h[search(e[3])] = search(e[0])\n",
    "        for e in equations:\n",
    "            if e[1] == \"!\":\n",
    "                if search(e[0]) == search(e[3]):\n",
    "                    return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isScramble(self, s1: str, s2: str) -> bool:\n",
    "        @cache\n",
    "        def search(i1, i2, length):\n",
    "            if s1[i1:i1+length] == s2[i2:i2+length]:\n",
    "                return True\n",
    "            if length == 1:\n",
    "                return False\n",
    "            for l in range(1, length):\n",
    "                if search(i1, i2+length-l, l) and search(i1+l, i2, length-l):\n",
    "                    return True\n",
    "                if search(i1, i2, l) and search(i1+l, i2+l, length-l):\n",
    "                    return True\n",
    "            return False\n",
    "        \n",
    "        return search(0, 0, len(s1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        height = len(matrix)\n",
    "        width = 0\n",
    "        for samp in matrix[0]:\n",
    "            width += 1\n",
    "        i = 0\n",
    "        while i < height:\n",
    "            if target > matrix[i][width-1]:\n",
    "                del matrix[i]\n",
    "                height = len(matrix)\n",
    "            elif target == matrix[i][width-1]:\n",
    "                return True\n",
    "            else:\n",
    "                i += 1\n",
    "        if matrix == []:\n",
    "            return False\n",
    "        i = 0\n",
    "        while i < width:\n",
    "            if target > matrix[height-1][i]:\n",
    "                for j in range(height):\n",
    "                    del matrix[j][i]\n",
    "                    width = 0\n",
    "                    for samp in matrix[0]:\n",
    "                        width += 1\n",
    "            elif target == matrix[height-1][i]:\n",
    "                return True\n",
    "            else:\n",
    "                i += 1\n",
    "        if matrix == []:\n",
    "            return False\n",
    "        for sonl in matrix:\n",
    "            for soni in sonl:\n",
    "                if target == soni:\n",
    "                    return True\n",
    "\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        # 不能双重二分，因为会导致某个维度上的target被跳过，而没有搜索到（假设目标值19）\n",
    "        # 固定x维，去对y维进行二分\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        x = m - 1\n",
    "        for i in range(m):\n",
    "            if matrix[i][0] > target:\n",
    "                x = i - 1\n",
    "\n",
    "        for i in range(x + 1):\n",
    "            left, right = -1, n\n",
    "            while left + 1 < right:\n",
    "                mid = (left + right) // 2\n",
    "                if matrix[i][mid] == target:\n",
    "                    return True\n",
    "                elif matrix[i][mid] > target:\n",
    "                    right = mid\n",
    "                else:\n",
    "                    left = mid\n",
    "\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        row, column = 0, len(matrix[0]) - 1\n",
    "        while column >= 0 and row < len(matrix):\n",
    "            if matrix[row][column] > target:\n",
    "                column -= 1\n",
    "            elif matrix[row][column] < target:\n",
    "                row += 1\n",
    "            else:\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        i, j = 0, len(matrix[0]) - 1\n",
    "        while i < len(matrix) and j >= 0:\n",
    "            if matrix[i][j] == target:\n",
    "                return True\n",
    "            elif matrix[i][j] < target:\n",
    "                i += 1\n",
    "            else:\n",
    "                j -= 1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        height = len(matrix)\n",
    "        width = 0\n",
    "        for samp in matrix[0]:\n",
    "            width += 1\n",
    "        i = 0\n",
    "        while i < height:\n",
    "            if target > matrix[i][width-1]:\n",
    "                del matrix[i]\n",
    "                height = len(matrix)\n",
    "            elif target == matrix[i][width-1]:\n",
    "                return True\n",
    "            else:\n",
    "                i += 1\n",
    "        if matrix == []:\n",
    "            return False\n",
    "        i = 0\n",
    "        while i < width:\n",
    "            if target > matrix[height-1][i]:\n",
    "                for j in range(height):\n",
    "                    del matrix[j][i]\n",
    "                    width = 0\n",
    "                    for samp in matrix[0]:\n",
    "                        width += 1\n",
    "            elif target == matrix[height-1][i]:\n",
    "                return True\n",
    "            else:\n",
    "                i += 1\n",
    "        if matrix == []:\n",
    "            return False\n",
    "        for sonl in matrix:\n",
    "            for soni in sonl:\n",
    "                if target == soni:\n",
    "                    return True\n",
    "\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        x, y = 0, n -1\n",
    "        while x < m and y >= 0:\n",
    "            if matrix[x][y] == target:\n",
    "                return True\n",
    "            \n",
    "            if matrix[x][y] > target:\n",
    "                y -= 1\n",
    "            else:\n",
    "                x += 1\n",
    "                \n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix, target: int) -> bool:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        def dfs(matrix, i, j):\n",
    "            if i < 0 or i >= m or j < 0 or j >= n or matrix[i][j] == 'inf':\n",
    "                return False\n",
    "            if matrix[i][j] == target:\n",
    "                matrix[i][j] = 'inf'\n",
    "                return True\n",
    "            elif matrix[i][j] > target:\n",
    "                matrix[i][j] = 'inf'\n",
    "                d1 = dfs(matrix, i - 1, j)\n",
    "                d2 = dfs(matrix, i, j - 1)\n",
    "            else:\n",
    "                matrix[i][j] = 'inf'\n",
    "                d1 = dfs(matrix, i + 1, j)\n",
    "                d2 = dfs(matrix, i, j + 1)\n",
    "            return d1 or d2\n",
    "        return dfs(matrix, 0, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        i = 0\n",
    "        j = len(matrix[0])-1\n",
    "        while i < len(matrix) and j >=0:\n",
    "            if matrix[i][j] > target:\n",
    "                j -= 1\n",
    "            elif matrix[i][j] < target:\n",
    "                i += 1\n",
    "            else:\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        # O(m*logn)\n",
    "        for i in range(m):\n",
    "            left, right = 0, n - 1\n",
    "            while left <= right:\n",
    "                mid = left + ((right - left) >> 1)\n",
    "                if matrix[i][mid] == target:\n",
    "                    return True\n",
    "                if matrix[i][mid] > target:\n",
    "                    right = mid - 1\n",
    "                else:\n",
    "                    left = mid + 1\n",
    "\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        i, j = 0, n-1\n",
    "        while i < m and j >= 0:\n",
    "            if matrix[i][j] == target:\n",
    "                return True\n",
    "            elif matrix[i][j] > target:\n",
    "                j -= 1\n",
    "            else:\n",
    "                i += 1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m = len(matrix)\n",
    "        n =len(matrix[0])\n",
    "        i, j = 0, 0\n",
    "\n",
    "        \n",
    "        while matrix[i][j] < target:\n",
    "            if i == m-1 and j == n-1:\n",
    "                return False\n",
    "            if i < m - 1:\n",
    "                i += 1\n",
    "            if j < n - 1:\n",
    "                j += 1\n",
    "            \n",
    "        if matrix[i][j] == target:\n",
    "            return True\n",
    "        oi = i\n",
    "        oj = j\n",
    "        i -= 1\n",
    "        while i >= 0 and j < n:\n",
    "            if matrix[i][j] == target:\n",
    "                return True\n",
    "            elif matrix[i][j] < target:\n",
    "                j += 1\n",
    "            else:\n",
    "                i -= 1\n",
    "        oj -= 1\n",
    "        while oj >= 0 and oi < m:\n",
    "            if matrix[oi][oj] == target:\n",
    "                return True\n",
    "            elif matrix[oi][oj] < target:\n",
    "                oi += 1\n",
    "            else:\n",
    "                oj -= 1\n",
    "            \n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m = len(matrix)\n",
    "        i, j = 0, len(matrix[0])-1\n",
    "        while i < m and j > -1:\n",
    "            if target == matrix[i][j]:\n",
    "                return True\n",
    "            elif target > matrix[i][j]:\n",
    "                i += 1\n",
    "            else:\n",
    "                j -= 1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        i, j = m-1, 0\n",
    "        while i>=0 and j<n:\n",
    "            if matrix[i][j]==target:\n",
    "                return True\n",
    "            elif matrix[i][j]<target:\n",
    "                j += 1\n",
    "            else:\n",
    "                i -= 1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        x, y = 0, n-1\n",
    "        while True:\n",
    "            if x >= m or y < 0:\n",
    "                return False\n",
    "            if matrix[x][y] < target:\n",
    "                x += 1\n",
    "            elif matrix[x][y] > target:\n",
    "                y -= 1\n",
    "            else:\n",
    "                return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        if not matrix or not matrix[0]:\n",
    "            return False\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        row, col = m - 1, 0\n",
    "        while row >= 0 and col < n:\n",
    "            if matrix[row][col] == target:\n",
    "                return True\n",
    "            elif matrix[row][col] > target:\n",
    "                row -= 1\n",
    "            else:\n",
    "                col += 1\n",
    "        return False\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        if not matrix: return 0\n",
    "        i = len(matrix)-1\n",
    "        while i >= 0:\n",
    "            if target < matrix[i][0]:\n",
    "                i -= 1\n",
    "            else:\n",
    "                if target in matrix[i]:return True\n",
    "                else: i-= 1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m = len(matrix)\n",
    "        if m == 0:\n",
    "            return False\n",
    "        n = len(matrix[0])\n",
    "        i = m - 1\n",
    "        j = 0\n",
    "\n",
    "        while i >= 0 and j < n:\n",
    "            if matrix[i][j] == target:\n",
    "                return True\n",
    "            if matrix[i][j] > target:\n",
    "                i -= 1\n",
    "            else:\n",
    "                j += 1\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix, target):\n",
    "        \"\"\"\n",
    "        :type matrix: List[List[int]]\n",
    "        :type target: int\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    " \n",
    "        if len(matrix) == 0:\n",
    "            return False\n",
    "        row = len(matrix)\n",
    "        col = len(matrix[0])\n",
    "        i = 0\n",
    "        j = col - 1\n",
    "        while i < row and j >= 0 :\n",
    "            if matrix[i][j] == target:\n",
    "                return True\n",
    "            elif matrix[i][j] > target:\n",
    "                j -= 1\n",
    "            else:\n",
    "                i += 1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        if not matrix:\n",
    "            return False\n",
    "        row_max=len(matrix)-1\n",
    "        col_max=len(matrix[0])-1\n",
    "\n",
    "        cur_row=row_max\n",
    "        cur_col=0\n",
    "\n",
    "        current=matrix[cur_row][cur_col]\n",
    "\n",
    "        while 1:\n",
    "            if current==target:\n",
    "                return True\n",
    "            elif target<current:\n",
    "                if cur_row>0:\n",
    "                    cur_row-=1\n",
    "                    current=matrix[cur_row][cur_col]\n",
    "                else:\n",
    "                    return False\n",
    "            elif target>current:\n",
    "                if cur_col<col_max:\n",
    "                    cur_col+=1\n",
    "                    current=matrix[cur_row][cur_col]\n",
    "                else:\n",
    "                    return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m,n=len(matrix),len(matrix[0])\n",
    "        shortDim = min(m,n)\n",
    "        for i in range(shortDim):\n",
    "            rowFound = self.binarySearchRow(matrix,i,target)\n",
    "            colFound = self.binarySearchCol(matrix,i,target)\n",
    "\n",
    "            if rowFound or colFound:\n",
    "                return True\n",
    "        return False\n",
    "\n",
    "    def binarySearchRow(self,matrix,row,target):\n",
    "        left=row\n",
    "        right=len(matrix[0])-1\n",
    "        while left<=right:\n",
    "            mid=left+(right-left)//2\n",
    "            if matrix[row][mid]==target:\n",
    "                return True\n",
    "            elif matrix[row][mid]<target:\n",
    "                left=mid+1\n",
    "            else:\n",
    "                right=mid-1\n",
    "        return False\n",
    "\n",
    "    def binarySearchCol(self,matrix,col,target):\n",
    "        left=col\n",
    "        right=len(matrix)-1\n",
    "        while left<=right:\n",
    "            mid = left+(right-left)//2\n",
    "            if matrix[mid][col]==target:\n",
    "                return True\n",
    "            elif matrix[mid][col]<target:\n",
    "                left=mid+1\n",
    "            else:\n",
    "                right=mid-1\n",
    "        return False\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\r\n",
    "        m, n = len(matrix), len(matrix[0])\r\n",
    "        row, col = 0, n - 1\r\n",
    "        while row < m and col >= 0:\r\n",
    "            if matrix[row][col] == target:\r\n",
    "                return True\r\n",
    "            elif matrix[row][col] < target:\r\n",
    "                row += 1\r\n",
    "            else:\r\n",
    "                col -= 1\r\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "\n",
    "        column = len(matrix[0])-1\n",
    "\n",
    "        rowid = len(matrix)-1\n",
    "        columid = 0\n",
    "\n",
    "        while rowid >=0 and columid <= column:\n",
    "            print(matrix[rowid][columid])\n",
    "            if matrix[rowid][columid] == target:\n",
    "                return True\n",
    "            \n",
    "            if matrix[rowid][columid] >= target:\n",
    "                rowid -= 1\n",
    "            else:\n",
    "                columid += 1\n",
    "        \n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix, target: int) -> bool:\n",
    "        root = matrix[0][-1]\n",
    "        while root!=target:\n",
    "            if target>root:\n",
    "                matrix = matrix[1:]\n",
    "            elif target < root:\n",
    "                matrix = [row[:-1] for row in matrix]\n",
    "            else:\n",
    "                #print('????')\n",
    "                return True\n",
    "            #print(matrix)\n",
    "            #tmp =\n",
    "            if not any(matrix):return False\n",
    "\n",
    "            root = matrix[0][-1]\n",
    "\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        mtx=matrix\n",
    "        while mtx and mtx[0]:\n",
    "            #print(mtx)\n",
    "            n=len(mtx)-1\n",
    "            #print(n,mtx[n][0],target)\n",
    "            if mtx[n][0]==target:           \n",
    "                #print(\"true\")     \n",
    "                return True\n",
    "                #break\n",
    "            elif mtx[n][0]>target:\n",
    "                mtx=mtx[:-1]\n",
    "            else:\n",
    "                for i in range(len(mtx)):\n",
    "                    tmp=mtx[i]\n",
    "                    tmp=tmp[1:]\n",
    "                    mtx[i]=tmp\n",
    "            \n",
    "\n",
    "        return False\n",
    "\n",
    "        \n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        def search(r1, r2, c1, c2):\n",
    "            # print(r1, r2, c1, c2)\n",
    "            nonlocal target\n",
    "            if r1 > r2 or c1 > c2: return False\n",
    "            if (r2-r1+1) * (c2-c1+1) <= 16:\n",
    "                for i in range(r1, r2 +1):\n",
    "                    for j in range(c1, c2+1):\n",
    "                        if matrix[i][j] == target:\n",
    "                            return True\n",
    "                return False\n",
    "            mid_r = (r1+r2)//2\n",
    "            mid_c = (c1+c2)//2\n",
    "            # print('mid:', mid_r, mid_c)\n",
    "            if matrix[mid_r][mid_c] == target: return True\n",
    "            if matrix[mid_r][mid_c] > target:\n",
    "                return (\n",
    "                    search(r1, mid_r-1, c1, c2) or\n",
    "                    search(mid_r, r2, c1, mid_c-1)\n",
    "                )\n",
    "            else:\n",
    "                return (\n",
    "                    search(mid_r+1, r2, c1, mid_c) or\n",
    "                    search(r1, r2, mid_c+1, c2)\n",
    "                )\n",
    "        return search(0, len(matrix)-1, 0, len(matrix[0])-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# 1 4 7 11 15       0,0,1,5  0,2\n",
    "# 0,0,0,5  0,0,1,2\n",
    "#          0 0 1 1\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m = len(matrix)\n",
    "        n = len(matrix[0])\n",
    "        \n",
    "        def search(origin_i, origin_j, i, j):\n",
    "          nonlocal target\n",
    "          #print(origin_i, origin_j, i, j)\n",
    "          if origin_i == i or origin_j == j:\n",
    "            return False\n",
    "          if i-origin_i == 1 and j-origin_j == 1:\n",
    "            return matrix[origin_i][origin_j] == target\n",
    "          \n",
    "          i2 = (origin_i+i) // 2\n",
    "          j2 = (origin_j+j) // 2\n",
    "          \n",
    "          if matrix[i2][j2] == target:\n",
    "            return True\n",
    "          elif matrix[i2][j2] > target:\n",
    "            return search(origin_i, origin_j, i2, j) or search(i2, origin_j, i, j2)\n",
    "          else:\n",
    "            #if i2 == i-1 and j2 == j-1:\n",
    "              #return False\n",
    "            #else:\n",
    "            return search(origin_i, j2+1, i, j) or search(i2+1, origin_j, i, j2+1)\n",
    "          \n",
    "          \n",
    "        return search(0, 0, m, n)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# 1 4 7 11 15       0,0,1,5  0,2\n",
    "# 0,0,0,5  0,0,1,2\n",
    "#          0 0 1 1\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m = len(matrix)\n",
    "        n = len(matrix[0])\n",
    "        \n",
    "        def search(origin_i, origin_j, i, j):\n",
    "          nonlocal target\n",
    "          #print(origin_i, origin_j, i, j)\n",
    "          if origin_i == i or origin_j == j:\n",
    "            return False\n",
    "          #if i-origin_i == 1 and j-origin_j == 1:\n",
    "            #return matrix[origin_i][origin_j] == target\n",
    "          \n",
    "          i2 = (origin_i+i) // 2\n",
    "          j2 = (origin_j+j) // 2\n",
    "          \n",
    "          if matrix[i2][j2] == target:\n",
    "            return True\n",
    "          elif matrix[i2][j2] > target:\n",
    "            return search(origin_i, origin_j, i2, j) or search(i2, origin_j, i, j2)\n",
    "          else:\n",
    "            #if i2 == i-1 and j2 == j-1:\n",
    "              #return False\n",
    "            #else:\n",
    "            return search(origin_i, j2+1, i, j) or search(i2+1, origin_j, i, j2+1)\n",
    "          \n",
    "          \n",
    "        return search(0, 0, m, n)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m = len(matrix)\n",
    "        n = len(matrix[0])\n",
    "        path = []\n",
    "        matrix1 = matrix\n",
    "        for m in matrix:\n",
    "            if target not in range(m[0],m[-1]+1):\n",
    "                matrix1.remove(m)         \n",
    "        \n",
    "        matrix_new = list(zip(*matrix1))\n",
    "        matrix_new1 = matrix_new\n",
    "        for l in matrix_new:\n",
    "            if target not in range(l[0],l[-1]+1):\n",
    "                matrix_new1.remove(l)\n",
    "        \n",
    "        for i in range(len(matrix_new1)):\n",
    "            for j in range(len(matrix_new1[0])):\n",
    "                if matrix_new1[i][j] == target:\n",
    "                    return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m = len(matrix)\n",
    "        n = len(matrix[0])\n",
    "        path = []\n",
    "        for m in matrix:\n",
    "            if target not in range(m[0],m[-1]+1):\n",
    "                matrix.remove(m)\n",
    "        \n",
    "        matrix_new = list(zip(*matrix))\n",
    "        for l in matrix_new:\n",
    "            if target not in range(l[0],l[-1]+1):\n",
    "                matrix_new.remove(l)\n",
    "        \n",
    "        for i in range(len(matrix_new)):\n",
    "            for j in range(len(matrix_new[0])):\n",
    "                if matrix_new[i][j] == target:\n",
    "                    return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool: \r\n",
    "        def search_dfs(min_x,max_x,min_y,max_y):\r\n",
    "            if min_x == max_x and min_y == max_y:\r\n",
    "                if matrix[min_x][min_y] == target:\r\n",
    "                    return True\r\n",
    "                else:\r\n",
    "                    return False\r\n",
    "            \r\n",
    "            for x in range(min_x,max_x+1):\r\n",
    "                if matrix[x][min_y] == target: return True\r\n",
    "                if matrix[x][min_y] > target:\r\n",
    "                    max_x = x-1\r\n",
    "                    break\r\n",
    "            for y in range(min_y,max_y+1):\r\n",
    "                if matrix[min_x][y] == target: return True\r\n",
    "                if matrix[min_x][y] > target:\r\n",
    "                    max_y = y-1\r\n",
    "                    break\r\n",
    "            if max_x <0 or max_y<0 or max_x<min_x or max_y<min_y: return False\r\n",
    "            if max_x > min_x: min_x+=1\r\n",
    "            if max_y > min_y: min_y+=1\r\n",
    "\r\n",
    "            return search_dfs(min_x,max_x,min_y,max_y)\r\n",
    "        \r\n",
    "        return search_dfs(0,len(matrix)-1,0,len(matrix[0])-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        # for i in range (0,len(matrix)):\n",
    "        #     for j in range(0,len(matrix[0])):\n",
    "        #         if matrix[i][j]==target:\n",
    "        #             return True\n",
    "        # return False\n",
    "\n",
    "        # row=len(matrix)\n",
    "        # column=len(matrix[0])-1\n",
    "        # i=0\n",
    "        # j=column\n",
    "        # while i < row and j>=0:\n",
    "        #     if matrix[i][j]==target:\n",
    "        #         return True\n",
    "        #     if matrix[i][j]>target:\n",
    "        #         j-=1\n",
    "        #     else:\n",
    "        #         i+=1\n",
    "        # return False\n",
    "\n",
    "        m=len(matrix)\n",
    "        n=len(matrix[0])\n",
    "        i=m-1\n",
    "        j=0\n",
    "        while i>=0 and j<n:\n",
    "            if matrix[i][j]==target:\n",
    "                return True\n",
    "            if matrix[i][j]>target:\n",
    "                i-=1\n",
    "            else:\n",
    "                j+=1\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        height = len(matrix)\n",
    "        width = 0\n",
    "        for samp in matrix[0]:\n",
    "            width += 1\n",
    "        i = 0\n",
    "        while i < height:\n",
    "            if target > matrix[i][width-1]:\n",
    "                del matrix[i]\n",
    "                height = len(matrix)\n",
    "            elif target == matrix[i][width-1]:\n",
    "                return True\n",
    "            else:\n",
    "                i += 1\n",
    "        if matrix == []:\n",
    "            return False\n",
    "        i = 0\n",
    "        while i < width:\n",
    "            if target > matrix[height-1][i]:\n",
    "                for j in range(height):\n",
    "                    del matrix[j][i]\n",
    "                    width = 0\n",
    "                    for samp in matrix[0]:\n",
    "                        width += 1\n",
    "            elif target == matrix[height-1][i]:\n",
    "                return True\n",
    "            else:\n",
    "                i += 1\n",
    "        if matrix == []:\n",
    "            return False\n",
    "        for sonl in matrix:\n",
    "            for soni in sonl:\n",
    "                if target == soni:\n",
    "                    return True\n",
    "\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        n, m = len(matrix), len(matrix[0])\n",
    "        state = [[False] * m for _ in range(n)]\n",
    "\n",
    "        return self.dfs(0, 0, matrix, target, state)\n",
    "\n",
    "    def dfs(self, i, j, matrix, target, state):\n",
    "        if matrix[i][j] == target:\n",
    "            return True\n",
    "\n",
    "        dirs = [[1, 0], [0, 1]]\n",
    "        right, down = len(matrix[0]) - 1, len(matrix) - 1\n",
    "        found = False\n",
    "        state[i][j] = True\n",
    "        for dir_ in dirs:\n",
    "            new_i, new_j = i + dir_[0], j + dir_[1]\n",
    "            if new_i <= down and new_j <= right and not state[new_i][new_j]:\n",
    "                if matrix[new_i][new_j] <= target:\n",
    "                    found = self.dfs(new_i, new_j, matrix, target, state)\n",
    "                if found:\n",
    "                    break\n",
    "        return found"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        return target in sum(matrix,[])\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\n",
    "    # def searchMatrix_recur(self, matrix, target, row_lo, col_lo, row_hi, col_hi):\n",
    "    #         if row_lo > row_hi or col_lo > col_hi or row_lo >= len(matrix) or col_lo >= len(matrix[0]):\n",
    "    #             return False\n",
    "    #         if row_lo == row_hi and col_lo == col_hi:\n",
    "    #             return matrix[row_lo][col_lo] == target\n",
    "    #         row_mid = row_lo + ((row_hi-row_lo)>>1)\n",
    "    #         col_mid = col_lo + ((col_hi-col_lo)>>1)\n",
    "    #         mid = matrix[row_mid][col_mid]\n",
    "    #         if mid == target:\n",
    "    #             return True\n",
    "    #         elif mid > target:\n",
    "    #             return self.searchMatrix_recur(matrix, target, row_lo, col_lo, row_mid-1, col_mid-1) or\\\n",
    "    #                 self.searchMatrix_recur(matrix, target, row_lo, col_mid, row_mid-1, col_hi) or\\\n",
    "    #                 self.searchMatrix_recur(matrix, target, row_mid, col_lo, row_hi, col_mid-1)\n",
    "    #         else:\n",
    "    #             return self.searchMatrix_recur(matrix, target, row_lo, col_mid+1, row_mid, col_hi) or\\\n",
    "    #                 self.searchMatrix_recur(matrix, target, row_mid+1, col_lo, row_hi, col_mid) or\\\n",
    "    #                 self.searchMatrix_recur(matrix, target, row_mid+1, col_mid+1, row_hi, col_hi)\n",
    "\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        # 法1，z字形查找\n",
    "        # i, j = 0, len(matrix[0]) - 1\n",
    "        # while i < len(matrix) and j >= 0:\n",
    "        #     if target == matrix[i][j]:\n",
    "        #         return True\n",
    "        #     elif target < matrix[i][j]:\n",
    "        #         j -= 1\n",
    "        #     else:\n",
    "        #         i += 1\n",
    "        # return False\n",
    "\n",
    "\n",
    "        # 分治\n",
    "        # if not matrix or not matrix[0]:\n",
    "        #     return False\n",
    "\n",
    "        # return self.searchMatrix_recur(matrix, target, 0, 0, len(matrix)-1, len(matrix[0])-1)\n",
    "\n",
    "        ################################################\n",
    "        if not matrix or not matrix[0]:\n",
    "            return False\n",
    "        def f(mat, xi, xj, yi, yj):\n",
    "            if xi > xj or yi > yj or xi >= len(mat) or yi >= len(mat[0]):\n",
    "                return False\n",
    "            if xi == xj and yi == yj:\n",
    "                return mat[xi][yi] == target\n",
    "            xm = (xi+xj)>>1\n",
    "            ym = (yi+yj)>>1\n",
    "            if target == mat[xm][ym]:\n",
    "                return True\n",
    "            elif target>mat[xm][ym]:\n",
    "                return f(mat, xi, xm, yi+1, yj) or f(mat, xm+1, xj, yi, ym) or f(mat, xm+1, xj, ym+1, yj)\n",
    "            else:\n",
    "                return f(mat, xi, xm-1, yi, ym-1) or f(mat, xi, xm-1, ym, yj) or f(mat, xm, xj, yi, ym-1)\n",
    "\n",
    "        return f(matrix, 0, len(matrix)-1, 0, len(matrix[0])-1)\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "\n",
    "        def dfs(r1: int, r2: int, c1: int, c2: int, d: int):\n",
    "\n",
    "            if c1 > c2 or r1 > r2:\n",
    "                return False\n",
    "            \n",
    "            if c1 == c2:\n",
    "                tmp = [matrix[x][c1] for x in range(m)]\n",
    "                i = bisect_right(tmp, target) - 1\n",
    "                if i >= 0 and tmp[i] == target:\n",
    "                    return True\n",
    "                else:\n",
    "                    return False\n",
    "            \n",
    "            if r1 == r2:\n",
    "                tmp = matrix[r1]\n",
    "                i = bisect_right(tmp, target) - 1\n",
    "                if i >= 0 and tmp[i] == target:\n",
    "                    return True\n",
    "                else:\n",
    "                    return False\n",
    "\n",
    "\n",
    "            if d == 0:\n",
    "                tmp = matrix[r1][c1:c2+1]\n",
    "                i = bisect_right(tmp, target) - 1\n",
    "                if i >= 0 and tmp[i] == target: return True\n",
    "                c2 = c1 + i\n",
    "\n",
    "            \n",
    "            if d == 1:\n",
    "                tmp = [matrix[x][c1] for x in range(r1, r2+1)]\n",
    "                i = bisect_right(tmp, target) - 1\n",
    "                if i >= 0 and tmp[i] == target: return True\n",
    "                r2 = r1 + i\n",
    "            \n",
    "            if d == 2:\n",
    "                tmp = matrix[r2][c1:c2+1]\n",
    "                i = bisect_left(tmp, target)\n",
    "                if i < len(tmp) and tmp[i] == target: return True\n",
    "                c1 = c1 + i\n",
    "            \n",
    "            if d == 3:\n",
    "                tmp = [matrix[x][c2] for x in range(r1, r2 + 1)]\n",
    "                i = bisect_left(tmp, target)\n",
    "                if i < len(tmp) and tmp[i] == target: return True\n",
    "                r1 = r1 + i\n",
    "\n",
    "            # for i in range(r1, r2+1):\n",
    "            #     print(matrix[i][c1:c2+1])\n",
    "            \n",
    "            # print('--------------')\n",
    "\n",
    "            d = (d + 1) % 4\n",
    "\n",
    "            return dfs(r1, r2, c1, c2, d)\n",
    "\n",
    "        \n",
    "        return dfs(0, m-1, 0, n-1, 0)\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        height = len(matrix)\n",
    "        width = 0\n",
    "        for samp in matrix[0]:\n",
    "            width += 1\n",
    "        i = 0\n",
    "        while i < height:\n",
    "            if target > matrix[i][width-1]:\n",
    "                del matrix[i]\n",
    "                height = len(matrix)\n",
    "            elif target == matrix[i][width-1]:\n",
    "                return True\n",
    "            else:\n",
    "                i += 1\n",
    "        if matrix == []:\n",
    "            return False\n",
    "        i = 0\n",
    "        while i < width:\n",
    "            if target > matrix[height-1][i]:\n",
    "                for j in range(height):\n",
    "                    del matrix[j][i]\n",
    "                    width = 0\n",
    "                    for samp in matrix[0]:\n",
    "                        width += 1\n",
    "            elif target == matrix[height-1][i]:\n",
    "                return True\n",
    "            else:\n",
    "                i += 1\n",
    "        if matrix == []:\n",
    "            return False\n",
    "        for sonl in matrix:\n",
    "            for soni in sonl:\n",
    "                if target == soni:\n",
    "                    return True\n",
    "\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        k = sum(matrix, [])\n",
    "        if target in k:\n",
    "            return True\n",
    "        else:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        #应该是要logn级别\n",
    "        #分解子问题，4分搜索就可以了，每次找中点然后分成四份\n",
    "\n",
    "\n",
    "        def QuadSearch(x,y,row,col,target):\n",
    "            if x<0 or y<0 or row<x or col<y:\n",
    "                return False\n",
    "            rowmid = (row-x)//2\n",
    "            colmid = (col-y)//2\n",
    "            \n",
    "            if target<matrix[x][y] or target>matrix[row][col]:\n",
    "                return False\n",
    "            if target == matrix[x+rowmid][y+colmid]:\n",
    "                return True\n",
    "            else:\n",
    "                return QuadSearch(x,y,x+rowmid,y+colmid,target) or QuadSearch(x+rowmid+1,y,row,y+colmid,target) or QuadSearch(x,y+colmid+1,x+rowmid,col,target) or QuadSearch(x+rowmid+1,y+colmid+1,row,col,target)\n",
    "\n",
    "        return QuadSearch(0,0,len(matrix)-1,len(matrix[0])-1,target)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "import pickle\n",
    "import zlib\n",
    "import base64\n",
    "count = 0\n",
    "test_case = []\n",
    "class Solution:\n",
    "    def right_code(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        col = 0\n",
    "        row = len(matrix) - 1\n",
    "        while True:\n",
    "            if target > matrix[row][col]:\n",
    "                col = col + 1\n",
    "            elif target < matrix[row][col]:\n",
    "                row = row - 1\n",
    "            else:\n",
    "                return True\n",
    "            if row < 0 or col >= len(matrix[0]):\n",
    "                return False\n",
    "\n",
    "    def searchMatrix(self, *args, **kwargs):\n",
    "        local = locals()\n",
    "        global count\n",
    "        count += 1\n",
    "        input = {}\n",
    "        for key, value in local.items():\n",
    "            if key != 'self':\n",
    "                input[key] = pickle.dumps(value)\n",
    "        cache = b''\n",
    "        if count < 1:\n",
    "            return pickle.loads(pickle.loads(zlib.decompress(base64.b64decode(cache)))[count-1][1])\n",
    "        if count >= 1 and count <= 129:\n",
    "            rtn = self.right_code(*args, **kwargs)\n",
    "            test_case.append((input, pickle.dumps(rtn)))\n",
    "            return rtn\n",
    "        else:\n",
    "            print(base64.b64encode(zlib.compress(pickle.dumps(test_case))))\n",
    "            return b'fjsefj'\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        visit = [[0] * n for _ in range(m)]\n",
    "        def search(matrix, visit, i, j, target):\n",
    "            if 0<=i<m and 0<=j<n:\n",
    "                if visit[i][j]:\n",
    "                    return False\n",
    "                visit[i][j] = 1\n",
    "                if matrix[i][j] == target:\n",
    "                    return True\n",
    "                elif matrix[i][j] < target:\n",
    "                    return search(matrix, visit, i+1, j, target) or search(matrix, visit, i, j+1, target)\n",
    "                elif matrix[i][j] > target:\n",
    "                    return search(matrix, visit, i-1, j, target) or search(matrix, visit, i, j-1, target)\n",
    "            else:\n",
    "                return False\n",
    "        return search(matrix, visit, 0, 0, target)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        visit = [[0] * n for _ in range(m)]\n",
    "        def search(matrix, visit, i, j, target):\n",
    "            m, n = len(matrix), len(matrix[0])\n",
    "            if 0<=i<m and 0<=j<n:\n",
    "                if visit[i][j]:\n",
    "                    return False\n",
    "                visit[i][j] = 1\n",
    "                if matrix[i][j] == target:\n",
    "                    return True\n",
    "                elif matrix[i][j] < target:\n",
    "                    return search(matrix, visit, i+1, j, target) or search(matrix, visit, i, j+1, target)\n",
    "                elif matrix[i][j] > target:\n",
    "                    return search(matrix, visit, i-1, j, target) or search(matrix, visit, i, j-1, target)\n",
    "            else:\n",
    "                return False\n",
    "        return search(matrix, visit, 0, 0, target)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        ans = False\n",
    "        def dfs(i, j):\n",
    "            nonlocal ans\n",
    "            if i >= m or j < 0:\n",
    "                return\n",
    "            if matrix[i][j] == target:\n",
    "                ans = True\n",
    "                return\n",
    "            if matrix[i][j] > target:\n",
    "                return dfs(i, j-1)\n",
    "            else:\n",
    "                return dfs(i+1, j)\n",
    "\n",
    "        dfs(0, n - 1)\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "import pickle\n",
    "import zlib\n",
    "import base64\n",
    "count = 0\n",
    "test_case = []\n",
    "class Solution:\n",
    "    def right_code(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        col = 0\n",
    "        row = len(matrix) - 1\n",
    "        while True:\n",
    "            if target > matrix[row][col]:\n",
    "                col = col + 1\n",
    "            elif target < matrix[row][col]:\n",
    "                row = row - 1\n",
    "            else:\n",
    "                return True\n",
    "            if row < 0 or col >= len(matrix[0]):\n",
    "                return False\n",
    "\n",
    "    def searchMatrix(self, *args, **kwargs):\n",
    "        local = locals()\n",
    "        global count\n",
    "        count += 1\n",
    "        input = {}\n",
    "        for key, value in local.items():\n",
    "            if key != 'self':\n",
    "                input[key] = pickle.dumps(value)\n",
    "        cache = b''\n",
    "        if count < 1:\n",
    "            return pickle.loads(pickle.loads(zlib.decompress(base64.b64decode(cache)))[count-1][1])\n",
    "        if count >= 1 and count <= 129:\n",
    "            rtn = self.right_code(*args, **kwargs)\n",
    "            test_case.append((input, pickle.dumps(rtn)))\n",
    "            return rtn\n",
    "        else:\n",
    "            print(base64.b64encode(zlib.compress(pickle.dumps(test_case))))\n",
    "            return b'fjsefj'\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        \n",
    "        trans = list(zip(*matrix))\n",
    "        m = len(matrix)\n",
    "        n = len(matrix[0])\n",
    "\n",
    "        def search(l, r, t, b):\n",
    "            if l > r or t > b or l >= n or t >= m:\n",
    "                return False\n",
    "\n",
    "            p1 = bisect_left(matrix[t], target)\n",
    "            if p1 < n and matrix[t][p1] == target:\n",
    "                return True\n",
    "            else:\n",
    "                r = p1 - 1\n",
    "            p2 = bisect_left(trans[l], target)\n",
    "            if p2 < m and trans[l][p2] == target:\n",
    "                return True\n",
    "            else:\n",
    "                b = p2 - 1\n",
    "            p3 = bisect_left(matrix[b], target)\n",
    "            if p3 < n and matrix[b][p3] == target:\n",
    "                return True\n",
    "            else:\n",
    "                l = p3\n",
    "            p4 = bisect_left(trans[r], target)\n",
    "            if p4 < m and trans[r][p4] == target:\n",
    "                return True\n",
    "            else:\n",
    "                t = p4\n",
    "            return search(l, r, t, b)\n",
    "        \n",
    "        return search(0, n - 1, 0, m -1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        i, j = len(matrix) - 1, 0\n",
    "        while i >= 0 and j < len(matrix[0]):\n",
    "            if matrix[i][j] == target:\n",
    "                return True\n",
    "            elif matrix[i][j] > target:\n",
    "                i -= 1\n",
    "            else:\n",
    "                j += 1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        tmp = sum(matrix,[])\n",
    "        return target in tmp\n",
    "\n",
    "\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        visited = [[0] * n for _ in range(m)]\n",
    "        def dfs(x, y):\n",
    "            if x >= m or y < 0:\n",
    "                return False\n",
    "            if visited[x][y]:\n",
    "                return False\n",
    "            visited[x][y] = 1\n",
    "            if matrix[x][y] == target:\n",
    "                return True\n",
    "            return dfs(x, y - 1) or dfs(x + 1, y)\n",
    "        return dfs(0, n - 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        for i in range(len(matrix)):\n",
    "            for j in range(len(matrix[0])):\n",
    "                if matrix[i][j] == target:\n",
    "                    return True\n",
    "        return False\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        r=[]\n",
    "        for e in matrix:\n",
    "            r.extend(e)\n",
    "        if target in r:\n",
    "            return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        row, col = len(matrix), len(matrix[0])\n",
    "        matrix_flatten = []\n",
    "        for m in matrix:\n",
    "            matrix_flatten += m\n",
    "        for m in matrix_flatten:\n",
    "            if m == target:\n",
    "                return True\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        i, j = 0, n - 1\n",
    "        while (0 <= i < m) and (0 <= j < n):\n",
    "            if target == matrix[i][j]:\n",
    "                return True\n",
    "            elif target < matrix[i][j]:\n",
    "                j -= 1\n",
    "            else:\n",
    "                i += 1\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        nums = []\n",
    "        for num in matrix: \n",
    "            nums = num + nums\n",
    "        nums.sort()\n",
    "        left = 0\n",
    "        right = len(nums) - 1\n",
    "        while left <= right:\n",
    "            mid = (left+right)//2\n",
    "            if nums[mid] == target:\n",
    "                return True\n",
    "            elif nums[mid] < target:\n",
    "                left = mid + 1\n",
    "            else:\n",
    "                right = mid - 1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m = len(matrix)\n",
    "        n = len(matrix[0])\n",
    "\n",
    "        i, j = m-1, 0\n",
    "        while 0<=i<m and 0<=j<n:\n",
    "            x = matrix[i][j]\n",
    "            if target==x:\n",
    "                return True\n",
    "            elif target>x:\n",
    "                j+=1\n",
    "            else:\n",
    "                i-=1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        for row in matrix:\n",
    "            left=0\n",
    "            right=len(row)-1\n",
    "            while left<=right:\n",
    "                mid=left+(right-left)//2\n",
    "                if row[mid]<target:\n",
    "                    left=mid+1\n",
    "                elif row[mid]>target:\n",
    "                    right=mid-1\n",
    "                else:\n",
    "                    return True\n",
    "        return False\n",
    "\n",
    "        for row in matrix:\n",
    "            for element in row:\n",
    "                if element==target:\n",
    "                    return True\n",
    "        return False\n",
    "\n",
    "        for row in matrix:\n",
    "            idx=bisect.bisect_left(row,target)\n",
    "            if idx<len(row) and row[idx]==target:\n",
    "                return True\n",
    "        return False\n",
    "\n",
    "        i=len(matrix)-1\n",
    "        j=0\n",
    "        while i>=0 and j<len(matrix[0]):\n",
    "            if matrix[i][j]>target:\n",
    "                i-=1\n",
    "            elif matrix[i][j]<target:\n",
    "                j+=1\n",
    "            else:\n",
    "                return True\n",
    "        return False\n",
    "\n",
    "\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        for i in range(len(matrix)):\n",
    "            if target in matrix[i]:\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        # 从左上开始，往哪都是增大\n",
    "        # 从右上开始往左减小，往下增大，不能往上往右\n",
    "        # 不存在走过了需要往上往右的情况，假设找5，走到了123，说明从4去了1，或者从6去了3\n",
    "        if not matrix:\n",
    "            return False\n",
    "        row, col = len(matrix), len(matrix[0])\n",
    "        i, j = 0, col-1\n",
    "        while i < row and j >= 0:\n",
    "            if matrix[i][j] == target:\n",
    "                return True\n",
    "            elif matrix[i][j] > target:\n",
    "                j -= 1\n",
    "            elif matrix[i][j] < target:\n",
    "                i += 1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m=len(matrix)\n",
    "        n=len(matrix[0])\n",
    "        for i in range(m):\n",
    "            for j in range(n):\n",
    "                if matrix[i][j]==target:\n",
    "                    return True\n",
    "                if matrix[i][j]>target:\n",
    "                    m=i\n",
    "                    n=j\n",
    "        return False\n",
    "       \n",
    "\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        for row in matrix:\n",
    "            for element in row:\n",
    "                if element == target:\n",
    "                    return True\n",
    "        return False\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        i,j = len(matrix)-1,0\n",
    "        while i>=0 and j<len(matrix[0]):\n",
    "            if matrix[i][j]>target: i-=1\n",
    "            elif matrix[i][j]<target: j+=1\n",
    "            else: return True\n",
    "        return False\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        if not matrix: return False\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        min_mn = min(m, n)\n",
    "        addm, addn = m-min_mn, n-min_mn\n",
    "        for i in range(min_mn):\n",
    "            if matrix[i][i]==target: return True\n",
    "            elif matrix[i][i]>target:\n",
    "                for j in range(i):\n",
    "                    if matrix[i][j]==target or matrix[j][i]==target: return True\n",
    "                \n",
    "        if m>n:\n",
    "            for i in range(m-min_mn):\n",
    "                if matrix[min_mn+i][min_mn-1]==target: return True\n",
    "                elif matrix[min_mn+i][min_mn-1]>target:\n",
    "                    for j in range(min_mn):\n",
    "                        if matrix[min_mn+i][j]==target: return True\n",
    "                    \n",
    "        elif m<n:\n",
    "            for i in range(n-min_mn):\n",
    "                if matrix[min_mn-1][min_mn+i]==target:return True\n",
    "                elif matrix[min_mn-1][min_mn+i]>target:\n",
    "                    for j in range(min_mn):\n",
    "                        if matrix[j][min_mn+i]==target: return True\n",
    "                    \n",
    "\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        for i in matrix:\n",
    "            if target in i:\n",
    "                return True\n",
    "                break\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m = len(matrix)\n",
    "        n = len(matrix[0])\n",
    "        for i in range(n-1, -1, -1):\n",
    "            if target >= matrix[0][i]:\n",
    "                for j in range(m):\n",
    "                    if target == matrix[j][i]:\n",
    "                        return True\n",
    "            elif i == 0:\n",
    "                return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        i, j = 0, n-1\n",
    "        while i < m and j >= 0:\n",
    "            if matrix[i][j] == target:\n",
    "                return True\n",
    "            elif matrix[i][j] > target:\n",
    "                j -= 1\n",
    "            else:\n",
    "                i += 1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        right = len(matrix[0]) - 1\n",
    "        down = len(matrix) - 1\n",
    "        i, j = 0, right\n",
    "        while i <= down and j >= 0:\n",
    "            if matrix[i][j] == target:\n",
    "                return True\n",
    "            elif matrix[i][j] < target:\n",
    "                i += 1\n",
    "            else:\n",
    "                j -= 1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        for i in range(len(matrix)):\n",
    "            for j in range(len(matrix[0])):\n",
    "                if matrix[i][j] == target:\n",
    "                    return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m = len(matrix)\n",
    "        n = len(matrix[0])\n",
    "\n",
    "        # for i in range(m):\n",
    "        #     if target >= matrix[i][0] and target <= matrix[i][n-1]:\n",
    "        #         for j in range(n):\n",
    "        #             if target == matrix[i][j]:\n",
    "        #                 return True\n",
    "        # return False\n",
    "        #### 对每一行二分查找\n",
    "        def binarySearch(nums, l, r, x):\n",
    "            if r >= l:\n",
    "                mid = (r - l)//2 + l\n",
    "                if x == nums[mid]:\n",
    "                    return True\n",
    "                elif x < nums[mid]:\n",
    "                    return binarySearch(nums, l, mid-1, x)\n",
    "                else:\n",
    "                    return binarySearch(nums, mid+1, r, x)\n",
    "            return False\n",
    "\n",
    "        for i in range(m):\n",
    "            if binarySearch(matrix[i], 0, n-1, target):\n",
    "                return True\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        # 如果每一行或每一列开头的元素，即该行/列的最小元素都比target大，说明该行/列不存在满足要求的元素，可不考虑；同理，最大元素比target小，也可以不考虑\n",
    "        m, n = len(matrix), len(matrix[0]) # m行, n列\n",
    "        row_start, row_end, col_start, col_end = 0, m-1, 0, n-1\n",
    "        # 缩减大值\n",
    "        while row_end >= 0 and col_end >= 0:\n",
    "            flag = False\n",
    "            if matrix[row_end][0] > target:\n",
    "                row_end -= 1\n",
    "                flag = True\n",
    "            if matrix[0][col_end] > target:\n",
    "                col_end -= 1\n",
    "                flag = True\n",
    "            if not flag: break\n",
    "        if row_end < 0 or col_end < 0: return False\n",
    "        # 缩减小值\n",
    "        while row_start <= row_end and col_start <= col_end:\n",
    "            flag = False\n",
    "            if matrix[row_start][col_end] < target:\n",
    "                row_start += 1\n",
    "                flag = True\n",
    "            if matrix[row_end][col_start] < target:\n",
    "                col_start += 1\n",
    "                flag = True\n",
    "            if not flag: break\n",
    "        if row_start > row_end or col_start > col_end: return False\n",
    "        for row in range(row_start, row_end+1):\n",
    "            for col in range(col_start, col_end+1):\n",
    "                if matrix[row][col] == target: return True\n",
    "        return False\n",
    "        \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        i = 0\n",
    "        j = len(matrix[0]) -1\n",
    "        while i <= len(matrix) -1 and j >=0:\n",
    "            if matrix[i][j] == target:\n",
    "                return True\n",
    "            if matrix[i][j] > target:\n",
    "                j -= 1\n",
    "            if matrix[i][j] < target:\n",
    "                i += 1\n",
    "        return False\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        for i in range(len(matrix)):\n",
    "            if matrix[i][0]>target:\n",
    "                return False\n",
    "            for j in range(len(matrix[0])):\n",
    "                if matrix[i][j]==target:\n",
    "                    return True\n",
    "            \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        x, y = len(matrix), len(matrix[0])\n",
    "        x_max, y_max = x, y\n",
    "        for i in range(x):\n",
    "            if matrix[i][0] < target:\n",
    "                continue\n",
    "            elif matrix[i][0] > target:\n",
    "                x_max = i\n",
    "            else:\n",
    "                return True\n",
    "        for i in range(y):\n",
    "            if matrix[0][i] < target:\n",
    "                continue\n",
    "            elif matrix[0][i] > target:\n",
    "                y_max = i\n",
    "            else:\n",
    "                return True\n",
    "        for i in range(x_max):\n",
    "            for j in range(y_max):\n",
    "                if matrix[i][j] == target:\n",
    "                    return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        i, j = 0, len(matrix[0]) - 1\n",
    "        while i < len(matrix) and j >= 0:\n",
    "            if matrix[i][j] == target: return True\n",
    "            elif matrix[i][j] < target: i += 1\n",
    "            else: j -= 1\n",
    "        return False\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        i, j = 0, len(matrix[0]) - 1\n",
    "\n",
    "        while matrix[i][j] != target:\n",
    "            if matrix[i][j]< target:\n",
    "                i += 1\n",
    "            else:\n",
    "                j -= 1\n",
    "            if i >= len(matrix) or j < 0:\n",
    "                return False\n",
    "        return True\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\r\n",
    "        m, n= len(matrix), len(matrix[0])\r\n",
    "\r\n",
    "        for i in range(m):\r\n",
    "            if matrix[i][0] == target:\r\n",
    "                return True\r\n",
    "            elif matrix[i][0] > target:\r\n",
    "                break\r\n",
    "        for j in range(n):\r\n",
    "            if matrix[0][j] == target:\r\n",
    "                return True\r\n",
    "            elif matrix[0][j] > target:\r\n",
    "                break\r\n",
    "        for k in range(0, i+1):\r\n",
    "            if target in matrix[k][0:j+1]:\r\n",
    "                return True\r\n",
    "        return False\r\n",
    "        \r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\r\n",
    "        m, n= len(matrix), len(matrix[0])\r\n",
    "\r\n",
    "        x, y = 0, n-1\r\n",
    "        while x < m and y >= 0:\r\n",
    "            if matrix[x][y] == target:\r\n",
    "                return True\r\n",
    "            else:\r\n",
    "                if matrix[x][y-1] >= target:\r\n",
    "                    y -= 1\r\n",
    "                else:\r\n",
    "                    x += 1\r\n",
    "        return False\r\n",
    "        \r\n",
    "\r\n",
    "        \r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m,n=len(matrix),len(matrix[0])\n",
    "        for i in range(0,m):\n",
    "            l=0\n",
    "            r=n-1\n",
    "            while l<=r:\n",
    "                mid=l+r>>1\n",
    "                if matrix[i][mid]>target:\n",
    "                    r=mid-1\n",
    "                elif matrix[i][mid]<target:\n",
    "                    l=mid+1\n",
    "                else:\n",
    "                    return True\n",
    "\n",
    "        return False\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\r\n",
    "        m, n= len(matrix), len(matrix[0])\r\n",
    "\r\n",
    "        x, y = 0, n-1\r\n",
    "        while x < m and y >= 0:\r\n",
    "            if matrix[x][y] == target:\r\n",
    "                return True\r\n",
    "            else:\r\n",
    "                if matrix[x][y-1] >= target:\r\n",
    "                    y -= 1\r\n",
    "                else:\r\n",
    "                    x += 1\r\n",
    "        return False\r\n",
    "        \r\n",
    "\r\n",
    "        \r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        i_limit, j_limit = m, n\n",
    "        i, j = 0, 0\n",
    "        i_prev, j_prev = i, j\n",
    "        while True:\n",
    "            while j < j_limit and matrix[i][j] < target:\n",
    "                j += 1\n",
    "            if j < j_limit and matrix[i][j] == target:\n",
    "                return True\n",
    "            else:\n",
    "                j -= 1\n",
    "\n",
    "            while i < i_limit and matrix[i][j] < target:\n",
    "                i += 1\n",
    "            if i == i_limit:\n",
    "                return False\n",
    "            elif matrix[i][j] == target:\n",
    "                return True\n",
    "            else:\n",
    "                # update i, j\n",
    "                j = 0\n",
    "            \n",
    "            if i == i_prev and j == j_prev:\n",
    "                return False\n",
    "            else:\n",
    "                # update i_prev, j_prev\n",
    "                i_prev, j_prev = i, j\n",
    "\n",
    "        \n",
    "            \n",
    "            \n",
    "\n",
    "\n",
    "\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        for row in range(m):\n",
    "            l, r = 0, n - 1\n",
    "            while l <= r:\n",
    "                mid = (l + r) // 2\n",
    "                if matrix[row][mid] == target: return True\n",
    "                elif matrix[row][mid] > target: r = mid - 1\n",
    "                else: l = mid + 1\n",
    "        return False\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        for row in matrix:\n",
    "            idx = bisect.bisect_left(row, target)\n",
    "            if idx < len(row) and row[idx] == target:\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        low, high = 0, len(matrix)-1\n",
    "        while low <= high:\n",
    "            mid = low + (high-low)//2\n",
    "            if matrix[mid][0] == target:\n",
    "                return True\n",
    "            elif matrix[mid][0] < target:\n",
    "                low = mid + 1\n",
    "            else:\n",
    "                high = mid - 1\n",
    "        # at this moment, high = target row\n",
    "        left, right = 0, len(matrix[0])-1\n",
    "        while left <= right:\n",
    "            mid = left + (right-left)//2\n",
    "            if matrix[high][mid] == target:\n",
    "                return True\n",
    "            elif matrix[high][mid] < target:\n",
    "                left = mid + 1\n",
    "            else:\n",
    "                right = mid - 1\n",
    "        return False\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: 'List[List[int]]', target: 'int') -> 'bool':\n",
    "        if matrix == [] or matrix[0] == []:\n",
    "            return False\n",
    "        l, r = 0, len(matrix) - 1\n",
    "        while l <= r:\n",
    "            m = (l + r) // 2\n",
    "            if matrix[m][0] == target:\n",
    "                return True\n",
    "            elif matrix[m][0] < target:\n",
    "                l = m + 1\n",
    "            else:\n",
    "                r = m - 1\n",
    "        if l >= len(matrix):\n",
    "            l -= 1\n",
    "        if matrix[l][0] == target:\n",
    "            return True\n",
    "        if matrix[l][0] > target:\n",
    "            while matrix[l][0] > target:\n",
    "                l -= 1\n",
    "                if l < 0:\n",
    "                    l += 1\n",
    "                    break\n",
    "                if matrix[l][0] == target:\n",
    "                    return True\n",
    "        else:\n",
    "            while matrix[l][0] < target and l < len(matrix):\n",
    "                l += 1\n",
    "                if l >= len(matrix):\n",
    "                    break\n",
    "                if matrix[l][0] == target:\n",
    "                    return True\n",
    "            l -= 1\n",
    "        l1, r1 = 0, len(matrix[0]) - 1\n",
    "        while l1 <= r1:\n",
    "            m1 = (l1 + r1) // 2\n",
    "            if matrix[l][m1] == target:\n",
    "                return True\n",
    "            elif matrix[l][m1] < target:\n",
    "                l1 = m1 + 1\n",
    "            else:\n",
    "                r1 = m1 - 1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix, target):\n",
    "        \"\"\"\n",
    "        :type matrix: List[List[int]]\n",
    "        :type target: int\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        if not len(matrix) or not len(matrix[0]):\n",
    "            return False\n",
    "        m, n= len(matrix), len(matrix[0])\n",
    "        lo, hi = 0, m * n\n",
    "        while lo < hi:\n",
    "            mid = (lo + hi)//2\n",
    "            m1 , n1 = divmod(mid, n)#m1,n1 分别代表mid在的行和列\n",
    "            print(m1,n1)\n",
    "            if matrix[m1][n1] <= target:\n",
    "                lo = mid + 1\n",
    "            else:\n",
    "                hi = mid\n",
    "                \n",
    "        if matrix[(lo-1)//n][(lo-1)%n] == target:\n",
    "            return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix, target):\n",
    "        \"\"\"\n",
    "        :type matrix: List[List[int]]\n",
    "        :type target: int\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        if  len(matrix)<1 or not matrix[0]:\n",
    "            return False\n",
    "        for i in range(len(matrix)-1,-1,-1):\n",
    "            if target>=matrix[i][0]:\n",
    "                if target in matrix[i]:\n",
    "                    return True\n",
    "                else:\n",
    "                    return False\n",
    "        return False\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: 'List[List[int]]', target: 'int') -> 'bool':\n",
    "        if not matrix or not matrix[0] or target > matrix[-1][-1] or target < matrix[0][0]:\n",
    "            return False\n",
    "        \n",
    "        h = len(matrix)\n",
    "        w = len(matrix[0])\n",
    "        \n",
    "        x = w - 1\n",
    "        y = 0\n",
    "        \n",
    "        while y < h and x >= 0:\n",
    "            if target == matrix[y][x]:\n",
    "                return True\n",
    "            elif target > matrix[y][x]:\n",
    "                y += 1\n",
    "            else:\n",
    "                x -= 1\n",
    "        \n",
    "        return False\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix, target):\n",
    "        \"\"\"\n",
    "        :type matrix: List[List[int]]\n",
    "        :type target: int\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        for i in matrix:\n",
    "            if target in set(i):\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: 'List[List[int]]', target: 'int') -> 'bool':\n",
    "        if matrix == [] or matrix==[[]]:\n",
    "            return False\n",
    "        if target<matrix[0][0] or target>matrix[-1][-1]:\n",
    "            return False\n",
    "\n",
    "        low = 0\n",
    "        high = len(matrix)-1\n",
    "\n",
    "        while(low<=high):\n",
    "            mid = int((low+high)/2)\n",
    "            if matrix[mid][0]>target:\n",
    "                high = mid-1\n",
    "            if matrix[mid][-1]<target:\n",
    "                low = mid+1\n",
    "            if matrix[mid][0]<=target and matrix[mid][-1]>=target:\n",
    "                break\n",
    "        row = matrix[mid]\n",
    "        low = 0\n",
    "        high = len(row)-1\n",
    "\n",
    "        while(low<=high):\n",
    "            mid = int((low + high) / 2)\n",
    "            if row[mid] == target:\n",
    "                return True\n",
    "            if row[mid]<target:\n",
    "                low = mid+1\n",
    "            if row[mid]>target:\n",
    "                high = mid-1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, A: List[List[int]], target: int) -> bool:\n",
    "        \n",
    "        \n",
    "        \n",
    "        # my solution ... \n",
    "        #  time: O(log(n*m))\n",
    "        # space: O(1)\n",
    "        \n",
    "        if not A or not A[0] or A[-1][-1] < target:\n",
    "            return False\n",
    "        n, m = len(A), len(A[0])\n",
    "        s, e = 0, n*m\n",
    "        while s < e:\n",
    "            mid = (s + e) // 2\n",
    "            i, j = mid // m, mid % m\n",
    "            if A[i][j] < target:\n",
    "                s = mid + 1\n",
    "            else:\n",
    "                e = mid\n",
    "        i, j = s // m, s % m\n",
    "        return False if i == n or A[i][j] != target else True\n",
    "        \n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        if len(matrix) == 0 or len(matrix[0]) == 0:\n",
    "            return False\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        row = -1\n",
    "        for i in range(m):\n",
    "            if matrix[i][0] == target:\n",
    "                return True\n",
    "            elif matrix[i][0] > target:\n",
    "                row = i -1 \n",
    "                break\n",
    "        if row < 0:\n",
    "            if matrix[-1][-1] >= target:\n",
    "                row = m -1\n",
    "            else:\n",
    "                return False\n",
    "        for j in range(n):\n",
    "            if matrix[row][j] == target:\n",
    "                return True\n",
    "            elif matrix[row][j] > target:\n",
    "                return False\n",
    "        return False\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\r\n",
    "        # def search(arr, lft, rht, target, is_row=False):\r\n",
    "        #     while lft <= rht:\r\n",
    "        #         mid = (lft + rht) >> 1\r\n",
    "        #         if arr[mid] == target:\r\n",
    "        #             return mid\r\n",
    "        #         if arr[mid] < target:\r\n",
    "        #             lft = mid + 1\r\n",
    "        #         else:\r\n",
    "        #             rht = mid - 1\r\n",
    "        #     if is_row:\r\n",
    "        #         return mid\r\n",
    "        #     else:\r\n",
    "        #         if arr[mid] == target:\r\n",
    "        #             return mid\r\n",
    "        #         else:\r\n",
    "        #             return -1\r\n",
    "\r\n",
    "        # if len(matrix) == 0 or len(matrix[0]) == 0:\r\n",
    "        #     return False\r\n",
    "        \r\n",
    "        # row, col = len(matrix), len(matrix[0])\r\n",
    "        # first_list = []\r\n",
    "        # for i in range(row):\r\n",
    "        #     first_list.append(matrix[i][0])\r\n",
    "        # row_idx = search(first_list, 0, len(first_list) - 1, target, True)\r\n",
    "\r\n",
    "        # if row_idx == -1:\r\n",
    "        #     return False\r\n",
    "        \r\n",
    "        # candidate = matrix[row_idx][:]\r\n",
    "        # if row_idx > 0:\r\n",
    "        #     candidate.extend(matrix[row_idx - 1])\r\n",
    "        # if row_idx < row - 1:\r\n",
    "        #     candidate.extend(matrix[row_idx + 1])\r\n",
    "        # candidate.sort()\r\n",
    "\r\n",
    "        # ret = search(candidate, 0, len(candidate) - 1, target)\r\n",
    "        # return ret != -1\r\n",
    "\r\n",
    "\r\n",
    "        # official solve\r\n",
    "        if len(matrix) == 0 or len(matrix[0]) == 0:\r\n",
    "            return False\r\n",
    "        \r\n",
    "        row, col = len(matrix), len(matrix[0])\r\n",
    "        lft, rht = 0, row * col - 1\r\n",
    "        while lft <= rht:\r\n",
    "            mid = (lft + rht) >> 1\r\n",
    "            mid_element = matrix[mid // col][mid % col]\r\n",
    "            if target == mid_element:\r\n",
    "                return True\r\n",
    "            elif target < mid_element:\r\n",
    "                rht = mid - 1\r\n",
    "            else:\r\n",
    "                lft = mid + 1\r\n",
    "        \r\n",
    "        return False\r\n",
    "        \r\n",
    "\r\n",
    "\r\n",
    "\r\n",
    "\r\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\r\n",
    "        def search(arr, lft, rht, target, is_row=False):\r\n",
    "            while lft <= rht:\r\n",
    "                mid = (lft + rht) >> 1\r\n",
    "                if arr[mid] == target:\r\n",
    "                    return mid\r\n",
    "                if arr[mid] < target:\r\n",
    "                    lft = mid + 1\r\n",
    "                else:\r\n",
    "                    rht = mid - 1\r\n",
    "            if is_row:\r\n",
    "                return mid\r\n",
    "            else:\r\n",
    "                if arr[mid] == target:\r\n",
    "                    return mid\r\n",
    "                else:\r\n",
    "                    return -1\r\n",
    "\r\n",
    "        if len(matrix) == 0 or len(matrix[0]) == 0:\r\n",
    "            return False\r\n",
    "        \r\n",
    "        row, col = len(matrix), len(matrix[0])\r\n",
    "        first_list = []\r\n",
    "        for i in range(row):\r\n",
    "            first_list.append(matrix[i][0])\r\n",
    "\r\n",
    "        # print(first_list)\r\n",
    "\r\n",
    "        row_idx = search(first_list, 0, len(first_list) - 1, target, True)\r\n",
    "        # print(row_idx)\r\n",
    "\r\n",
    "        if row_idx == -1:\r\n",
    "            return False\r\n",
    "        \r\n",
    "        candidate = matrix[row_idx][:]\r\n",
    "        if row_idx > 0:\r\n",
    "            candidate.extend(matrix[row_idx - 1])\r\n",
    "        if row_idx < row - 1:\r\n",
    "            candidate.extend(matrix[row_idx + 1])\r\n",
    "        candidate.sort()\r\n",
    "        # print(candidate)\r\n",
    "\r\n",
    "        ret = search(candidate, 0, len(candidate) - 1, target)\r\n",
    "        # print(ret)\r\n",
    "\r\n",
    "        return ret != -1\r\n",
    "\r\n",
    "\r\n",
    "\r\n",
    "\r\n",
    "\r\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        if not matrix or not matrix[0]:\n",
    "            return False\n",
    "\n",
    "        row_array = [array[0] for array in matrix]\n",
    "        if row_array[0] > target:\n",
    "                return False\n",
    "\n",
    "        def binary_search(array, left, right, target):\n",
    "            if right >= left:\n",
    "                mid = left + (right - left) // 2\n",
    "                if array[mid] == target:\n",
    "                    return mid\n",
    "                elif  array[mid] > target:\n",
    "                    return binary_search(array, left, mid - 1, target)\n",
    "                else:\n",
    "                    return binary_search(array, mid + 1, right, target)\n",
    "            else:\n",
    "                return right\n",
    "        \n",
    "        idx_row = binary_search(row_array, 0, len(row_array) - 1, target)\n",
    "        return target in matrix[idx_row]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        if len(matrix) == 0 or len(matrix[0]) == 0:\n",
    "            return False\n",
    "        # 先对行进行分类搜索\n",
    "        left, right =0, len(matrix) - 1\n",
    "\n",
    "        while left <= right:\n",
    "            mid = (left + right) // 2\n",
    "            if target == matrix[mid][0]:\n",
    "                return True\n",
    "            if target < matrix[mid][0]:\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                left = mid + 1\n",
    "        row = right\n",
    "        left, right = 0, len(matrix[0]) - 1\n",
    "\n",
    "        while left <= right:\n",
    "            mid = (left + right) // 2\n",
    "            if target == matrix[row][mid]:\n",
    "                return True\n",
    "            if target < matrix[row][mid]:\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                left = mid + 1\n",
    "        \n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        if len(matrix) == 0 or len(matrix[0]) == 0:\n",
    "            return False\n",
    "        \n",
    "\n",
    "        row_num = len(matrix)\n",
    "        col_num = len(matrix[0])\n",
    "        total = row_num*col_num\n",
    "        start = 0\n",
    "        end = total-1\n",
    "\n",
    "        while start+1 < end:\n",
    "            mid = start+(end-start)//2\n",
    "            r = mid//col_num\n",
    "            c = mid%col_num\n",
    "            if matrix[r][c] == target:\n",
    "                return True\n",
    "            elif matrix[r][c] < target:\n",
    "                start = mid\n",
    "            else:\n",
    "                end = mid\n",
    "        \n",
    "        if matrix[start//col_num][start%col_num] == target or matrix[end//col_num][end%col_num] == target:\n",
    "            return True\n",
    "        else:\n",
    "            return False "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    from bisect import bisect_left,bisect_right\n",
    "    \n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        class Tmp:\n",
    "            def __init__(self,data):\n",
    "                self.data=data\n",
    "            def __getitem__(self,i):\n",
    "                return self.data[i][0]\n",
    "            def __len__(self):\n",
    "                return len(self.data)\n",
    "        data=Tmp(matrix)\n",
    "        t=bisect_right(data,target)-1\n",
    "        t2=bisect_left(matrix[t],target)\n",
    "        if t2>=len(matrix[t]):\n",
    "            return False\n",
    "        # print(t,t2,matrix[t][t2])\n",
    "        return matrix[t][t2]==target\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        n,m=len(matrix),len(matrix[0])\n",
    "        l,r=0,n*m\n",
    "        while r>l:\n",
    "            mid=l+r>>1\n",
    "            if matrix[mid//m][mid%m]<target:\n",
    "                l=mid+1\n",
    "            elif matrix[mid//m][mid%m]>target:\n",
    "                r=mid\n",
    "            else:\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        M, N = len(matrix), len(matrix[0])\n",
    "        left, right = 0, M * N - 1\n",
    "        while left <= right:\n",
    "            mid = left + (right - left) // 2\n",
    "            cur = matrix[mid // N][mid % N]\n",
    "            if cur == target:\n",
    "                return True\n",
    "            elif cur < target:\n",
    "                left = mid + 1\n",
    "            else:\n",
    "                right = mid - 1\n",
    "        return False\n",
    "        \n",
    "\n",
    "             \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m = len(matrix)\n",
    "        n = len(matrix[0])\n",
    "        \n",
    "        # 先二分找到行\n",
    "        left_i, right_i = 0 , m\n",
    "        while left_i < right_i :\n",
    "            mid = (left_i + right_i) // 2\n",
    "            if matrix[mid][0] == target :\n",
    "                return True\n",
    "            elif matrix[mid][0] > target :\n",
    "                right_i = mid\n",
    "            else :\n",
    "                left_i = mid + 1\n",
    "        # 在第left_i - 1行里\n",
    "        print(left_i-1)\n",
    "        left_j, right_j = 0, n\n",
    "        while left_j < right_j :\n",
    "            mid = (left_j + right_j) // 2\n",
    "            if matrix[left_i-1][mid] == target :\n",
    "                return True\n",
    "            elif matrix[left_i-1][mid] > target :\n",
    "                right_j = mid\n",
    "            else :\n",
    "                left_j = mid + 1\n",
    "        \n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        # 主要思路 将矩阵变成一个数组，然后利用一次二分查找找到对应的值，返回True\n",
    "        # 第一步 进行边界条件的限定\n",
    "        if matrix == None or len(matrix) ==0:\n",
    "            return False\n",
    "        # 先将矩阵变成一维数组  \n",
    "        row = len(matrix)\n",
    "        col = len(matrix[0])\n",
    "        l= 0\n",
    "        r = row*col -1\n",
    "        while l <= r:\n",
    "            m = l +(r-l)//2\n",
    "            if matrix[m//col][m%col] == target:\n",
    "                return True\n",
    "            elif matrix[m//col][m%col] < target:\n",
    "                l = m+1\n",
    "            else:\n",
    "                r = m -1\n",
    "        return False\n",
    "            \n",
    "        \n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        if len(matrix)==0 or len(matrix[0])==0:\n",
    "            return False\n",
    "        n = len(matrix)\n",
    "        if matrix[n-1][0]==target:\n",
    "            return True\n",
    "        elif matrix[n-1][0]>target:\n",
    "            return self.searchMatrix(matrix[:n-1], target)\n",
    "        else:\n",
    "            return self.searchMatrix([col[1:] for col in matrix] ,target)\n",
    "        \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        # 将矩阵变为列表\n",
    "        arr = [int(i) for i in str(matrix).replace('[', '').replace(']', '').replace(' ', '').split(',')]\n",
    "\n",
    "        # 二分查找\n",
    "        if len(arr) == 1:\n",
    "            return arr[0] == target\n",
    "\n",
    "        l, r = -1, len(arr)\n",
    "        while l < r - 1:\n",
    "            m = (l + r) // 2\n",
    "            if arr[m] == target:\n",
    "                return True\n",
    "            if arr[m] < target:\n",
    "                l = m\n",
    "            else:\n",
    "                r = m\n",
    "\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "\n",
    "        i, j = 0, m * n - 1\n",
    "        while i <= j:\n",
    "            k = (i + j) // 2\n",
    "            tmp = matrix[k//n][k%n]\n",
    "            if tmp == target:\n",
    "                return True\n",
    "            elif tmp < target:\n",
    "                i += 1\n",
    "            else:\n",
    "                j -= 1\n",
    "        \n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        def binary_search(nums,target):\n",
    "            left = 0\n",
    "            right = len(nums) - 1\n",
    "            while left <= right:\n",
    "                mid =  (left + right) // 2\n",
    "                if nums[mid] == target:\n",
    "                    return mid\n",
    "                elif nums[mid] < target:\n",
    "                    left = mid +1\n",
    "                else:\n",
    "                    right = mid - 1\n",
    "            else:\n",
    "                return None\n",
    "        for i in range(len(matrix)):\n",
    "            if binary_search(matrix[i], target) is not None:\n",
    "                return True\n",
    "        return False\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:\n",
    "        # def binary_search(nums,target):\n",
    "        #     left = 0\n",
    "        #     right = len(nums) - 1\n",
    "        #     while left <= right:\n",
    "        #         mid =  (left + right) // 2\n",
    "        #         if nums[mid] == target:\n",
    "        #             return mid\n",
    "        #         elif nums[mid] < target:\n",
    "        #             left = mid +1\n",
    "        #         else:\n",
    "        #             right = mid - 1\n",
    "        #     else:\n",
    "        #         return None\n",
    "        # for i in range(len(matrix)):\n",
    "        #     if binary_search(matrix[i], target) is not None:\n",
    "        #         return True\n",
    "        #     else:\n",
    "        #         return False\n",
    "        for i in range(len(matrix)):\n",
    "            left = 0\n",
    "            right = len(matrix[i]) - 1\n",
    "            while left <= right:\n",
    "                mid = (left + right) // 2\n",
    "                if matrix[i][mid] == target:\n",
    "                    return True\n",
    "                elif matrix[i][mid] < target:\n",
    "                    left = mid + 1\n",
    "                else:\n",
    "                    right = mid - 1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:\n",
    "        if root is None:\n",
    "            return root\n",
    "        # find node\n",
    "        node = root\n",
    "        while node and node.val !=val:\n",
    "            if node.val>val:\n",
    "                node = node.left\n",
    "            else:\n",
    "                node = node.right\n",
    "        if node is None:\n",
    "            return None\n",
    "        else:\n",
    "            return node\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def searchBST(self, root: 'TreeNode', val: 'int') -> 'TreeNode':\n",
    "        if not root:\n",
    "            return None\n",
    "        if root.val==val:\n",
    "            return root\n",
    "        if root.val<val:\n",
    "            return self.searchBST(root.right,val)\n",
    "        if root.val>val:\n",
    "            return self.searchBST(root.left,val)\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def searchBST(self, root: 'TreeNode', val: 'int') -> 'TreeNode':\n",
    "        if not root:\n",
    "            return None\n",
    "        if root.val==val:\n",
    "            return root\n",
    "        if root.val!=val:\n",
    "            return self.searchBST(root.left,val) or self.searchBST(root.right,val)\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def searchBST(self, root, val):\n",
    "        \"\"\"\n",
    "        :type root: TreeNode\n",
    "        :type val: int\n",
    "        :rtype: TreeNode\n",
    "        \"\"\"\n",
    "        while root:\n",
    "            if root.val == val:\n",
    "                return root\n",
    "            elif root.val > val:\n",
    "                root = root.left\n",
    "            else:\n",
    "                root = root.right\n",
    "        return None\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def searchBST(self, root, val):\n",
    "        \"\"\"\n",
    "        :type root: TreeNode\n",
    "        :type val: int\n",
    "        :rtype: TreeNode\n",
    "        \"\"\"\n",
    "        if root is None:\n",
    "                return\n",
    "        list = []\n",
    "        #returnArr = []\n",
    "        while True:\n",
    "            if root.val == val:\n",
    "                return root\n",
    "            #returnArr.append(root.val)\n",
    "            print(root.val)\n",
    "            if root.right:\n",
    "                list.append(root.right)\n",
    "            if root.left:\n",
    "                root = root.left\n",
    "            elif len(list)>0:\n",
    "                root = list.pop()\n",
    "            else:\n",
    "                return\n",
    "        #return returnArr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def searchBST(self, root: TreeNode, val: int) -> TreeNode:\n",
    "        if not root:\n",
    "            return None\n",
    "        if root.val == val:\n",
    "            return root\n",
    "        else:\n",
    "            if root.val > val:\n",
    "                return self.searchBST(root.left,val)\n",
    "            else:\n",
    "                return self.searchBST(root.right,val)\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def searchBST(self, root: TreeNode, val: int) -> TreeNode:\n",
    "        if not root:\n",
    "            return None\n",
    "        if root.val==val:\n",
    "            return root\n",
    "        root.left = self.searchBST(root.left,val)\n",
    "        root.right = self.searchBST(root.right,val)\n",
    "        return root.left or root.right"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def searchBST(self, root: TreeNode, val: int) -> TreeNode:\n",
    "        if not root or root.val == val:\n",
    "            return root\n",
    "        left = self.searchBST(root.left, val)\n",
    "        right = self.searchBST(root.right, val)\n",
    "        if left and left.val == val:\n",
    "            return left\n",
    "        if right and right.val == val:\n",
    "            return right \n",
    "        return None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def searchBST(self, root: TreeNode, val: int) -> TreeNode:\n",
    "        if root == None:\n",
    "            return\n",
    "        if root.val > val:\n",
    "            return self.searchBST(root.left,val)\n",
    "        elif root.val < val:\n",
    "            return self.searchBST(root.right,val)\n",
    "        else:\n",
    "            return root"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def searchBST(self, root: TreeNode, val: int) -> TreeNode:\n",
    "        if root is None: return None\n",
    "        if root.val == val: return root\n",
    "        elif root.val > val: return self.searchBST(root.left, val)\n",
    "        return self.searchBST(root.right, val)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def searchBST(self, root: TreeNode, val: int) -> TreeNode:\n",
    "        stack = [root]\n",
    "\n",
    "        while stack:\n",
    "            node = stack.pop()\n",
    "            \n",
    "            if not node:\n",
    "                continue\n",
    "\n",
    "            if node.val == val:\n",
    "                return node\n",
    "\n",
    "            if node.val > val:\n",
    "                stack.append(node.left)\n",
    "            elif node.val < val:\n",
    "                stack.append(node.right)\n",
    "\n",
    "        return"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def searchBST(self, root: TreeNode, val: int) -> TreeNode:\n",
    "        while root:\n",
    "            if val>root.val:\n",
    "                root=root.right\n",
    "            elif val<root.val:\n",
    "                root=root.left\n",
    "            elif root.val==val:\n",
    "                return root\n",
    "        return None\n",
    "    \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def searchBST(self, root: TreeNode, val: int) -> TreeNode:\n",
    "        if not root:\n",
    "            return None\n",
    "        if root.val == val:\n",
    "            return root\n",
    "        if root.val > val and root.left:\n",
    "            return self.searchBST(root.left, val)\n",
    "        if root.val < val and root.right:\n",
    "            return self.searchBST(root.right, val)\n",
    "        return None\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def searchBST(self, root: TreeNode, val: int) -> TreeNode:  # 递归解法\n",
    "        if root is None:\n",
    "            return None\n",
    "        if val == root.val:\n",
    "            return root\n",
    "        elif val < root.val:\n",
    "            return self.searchBST(root.left, val)\n",
    "        else:\n",
    "            return self.searchBST(root.right, val)\n",
    "\n",
    "\n",
    "# class Solution: \n",
    "#     def searchBST(self, root: TreeNode, val: int) -> TreeNode:  # 非递归解法\n",
    "#         if root is None:\n",
    "#             return None\n",
    "#         while root:\n",
    "#             if val == root.val:\n",
    "#                 return root\n",
    "#             elif val < root.val:\n",
    "#                 root = root.left\n",
    "#             else:\n",
    "#                 root = root.right\n",
    "#         return None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def searchBST(self, root: TreeNode, val: int) -> TreeNode:\n",
    "        if not root:\n",
    "            return None\n",
    "        while root:\n",
    "            if val>root.val:\n",
    "                root = root.right\n",
    "            elif val < root.val:\n",
    "                root = root.left\n",
    "            elif root.val == val:\n",
    "                return root\n",
    "        return None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def searchBST(self, root: TreeNode, val: int) -> TreeNode:\n",
    "        while root:\n",
    "            if root.val==val:\n",
    "                return root\n",
    "            elif root.val>val:\n",
    "                root=root.left\n",
    "            elif root.val<val:\n",
    "                root=root.right\n",
    "        return None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def searchBST(self, root: TreeNode, val: int) -> TreeNode:\n",
    "        # 递归\n",
    "        if not root or root.val == val:\n",
    "            return root\n",
    "        root.left = self.searchBST(root.left, val)\n",
    "        root.right = self.searchBST(root.right, val)\n",
    "        return root.left or root.right\n",
    "        # return None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def searchBST(self, root: TreeNode, val: int) -> TreeNode:\n",
    "        p = root\n",
    "        while p:\n",
    "            if p.val < val:\n",
    "                p = p.right\n",
    "            elif p.val > val:\n",
    "                p = p.left\n",
    "            else:\n",
    "                return p\n",
    "        return None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def searchBST(self, root: TreeNode, val: int) -> TreeNode:\n",
    "        # 二叉搜索树的迭代\n",
    "        while root:\n",
    "            if root.val == val:\n",
    "                return root\n",
    "            elif root.val > val:\n",
    "                root = root.left\n",
    "            else:\n",
    "                root = root.right\n",
    "        return None\n",
    "\n",
    "        # 一提到二叉树遍历的迭代法，可能立刻想起使用 栈(stack) 来模拟深度遍历 DFS\n",
    "        # 使用队列(deque)来模拟广度遍历。\n",
    "\n",
    "        # 对于二叉搜索树可就不一样了，因为二叉搜索树的特殊性，也就是节点的有序性，可以不使用辅助栈或者队列\n",
    "        # 就可以写出迭代法。对于一般二叉树，递归过程中还有回溯的过程.\n",
    "\n",
    "        # 迭代\n",
    "        # if not root:\n",
    "        #     return None\n",
    "        # stack = [root]\n",
    "\n",
    "        # while stack:\n",
    "        #     cur = stack.pop()\n",
    "        #     if cur.val == val:\n",
    "        #         return cur\n",
    "        #     else:\n",
    "        #         if cur.right:\n",
    "        #             stack.append(cur.right)\n",
    "        #         if cur.left:\n",
    "        #             stack.append(cur.left)\n",
    "        # return None\n",
    "\n",
    "        # DFS\n",
    "        # if not root or root.val == val:\n",
    "        #     return root\n",
    "        # if root.val > val:\n",
    "        #     return self.searchBST(root.left,val)\n",
    "        # if root.val < val:\n",
    "        #     return self.searchBST(root.right,val)\n",
    "\n",
    "        # 层序遍历 BFS\n",
    "        # if not root:\n",
    "        #     return None\n",
    "        # que = collections.deque([root])\n",
    "\n",
    "        # while que:\n",
    "        #     n = len(que)\n",
    "        #     for _ in range(n):\n",
    "        #         cur = que.popleft()\n",
    "        #         if cur.val == val:\n",
    "        #             return cur\n",
    "        #         if cur.left:\n",
    "        #             que.append(cur.left)\n",
    "        #         if cur.right:\n",
    "        #             que.append(cur.right)\n",
    "        # return None\n",
    "\n",
    "\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:\n",
    "        if not root:\n",
    "            return None\n",
    "        \n",
    "        while root:\n",
    "            if root.val == val:\n",
    "                return root\n",
    "            elif root.val < val:\n",
    "                root = root.right\n",
    "            else:\n",
    "                root = root.left\n",
    "        \n",
    "        return None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:\n",
    "        if root==None:\n",
    "            return None\n",
    "        if root.val == val:\n",
    "            return root\n",
    "        root.left = self.searchBST(root.left,val)\n",
    "        root.right = self.searchBST(root.right,val)\n",
    "        if root.left:\n",
    "            return root.left\n",
    "        if root.right:\n",
    "            return root.right"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:\n",
    "        if not root:\n",
    "            return None\n",
    "        \n",
    "        if root.val == val:\n",
    "            return root\n",
    "        \n",
    "        root.left = self.searchBST(root.left,val)\n",
    "        root.right = self.searchBST(root.right,val)\n",
    "\n",
    "        if root.left:\n",
    "            return root.left\n",
    "        if root.right:\n",
    "            return root.right"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:\n",
    "        # res = []\n",
    "\n",
    "        def dfs(node):          \n",
    "            if node is None:\n",
    "                return\n",
    "\n",
    "            if node.val == val:\n",
    "                return node\n",
    "            if node.val < val:\n",
    "                r = dfs(node.right)\n",
    "                if r is not None:\n",
    "                    return r\n",
    "\n",
    "            if node.val > val:\n",
    "                l = dfs(node.left)\n",
    "                if l is not None:\n",
    "                    return l\n",
    "         \n",
    "        s = dfs(root)\n",
    "        print(s)\n",
    "        return s\n",
    "        # if s is not None:\n",
    "        #     return s\n",
    "        # else:\n",
    "        #     return None\n",
    "        # print(s)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:\n",
    "        while root:\n",
    "            print(root)\n",
    "            if root.val == val:\n",
    "                return root\n",
    "            if root.val < val:\n",
    "                root = root.right\n",
    "            else:\n",
    "                root = root.left\n",
    "        return None\n",
    "        \n",
    "# class Solution:\n",
    "#     def searchBST(self, root: TreeNode, val: int) -> TreeNode:\n",
    "#         while root:\n",
    "#             if val == root.val:\n",
    "#                 return root\n",
    "#             root = root.left if val < root.val else root.right\n",
    "#         return None\n",
    "\n",
    "# 作者：LeetCode-Solution\n",
    "# 链接：https://leetcode.cn/problems/search-in-a-binary-search-tree/solution/er-cha-sou-suo-shu-zhong-de-sou-suo-by-l-d8zi/\n",
    "# 来源：力扣（LeetCode）\n",
    "# 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:\n",
    "        def dfs(node):\n",
    "            if node == None:\n",
    "                return None\n",
    "            \n",
    "            if node.val == val:\n",
    "                return node\n",
    "            if val < node.val:\n",
    "                node.left = dfs(node.left)\n",
    "                return node.left\n",
    "            if val > node.val:\n",
    "                node.right = dfs(node.right)\n",
    "                return node.right\n",
    "        return dfs(root)\n",
    "        \n",
    "  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:\n",
    "        ret = None\n",
    "\n",
    "        def dfs(node):\n",
    "            nonlocal ret\n",
    "            if node is None: return\n",
    "            if node.val == val:\n",
    "                ret = node\n",
    "                return\n",
    "            dfs(node.left)\n",
    "            dfs(node.right)\n",
    "        \n",
    "        dfs(root)\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "#Definition for a binary tree node.\n",
    "class TreeNode:\n",
    "    def __init__(self, val=0, left=None, right=None):\n",
    "        self.val = val\n",
    "        self.left = left\n",
    "        self.right = right\n",
    "class Solution:\n",
    "    def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:\n",
    "        if root==None:\n",
    "            return None\n",
    "        if val<root.val:\n",
    "            return self.searchBST(root.left,val)\n",
    "        if val>root.val:\n",
    "            return self.searchBST(root.right,val)\n",
    "        return root"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader, target):\n",
    "        \"\"\"\n",
    "        :type reader: ArrayReader\n",
    "        :type target: int\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        if reader.get(0) == target:\n",
    "            return 0\n",
    "\n",
    "        right: int = 1\n",
    "        while reader.get(right) != 2147483647 and reader.get(right) < target:\n",
    "            right *= 2\n",
    "            \n",
    "        if reader.get(right) == target:\n",
    "            return right\n",
    "        \n",
    "        left = right // 2\n",
    "        while left <= right:\n",
    "            middle = (left + right) // 2\n",
    "            # print(\"[{:d}] = {:d}  [{:d}] = {:d}  [{:d}] = {:d}\".format(\n",
    "            #     left, reader.get(left),\n",
    "            #     middle, reader.get(middle),\n",
    "            #     right, reader.get(right)\n",
    "            # ))\n",
    "            if reader.get(middle) == 2147483647:\n",
    "                right = middle - 1\n",
    "            elif target == reader.get(middle):\n",
    "                return middle\n",
    "            elif target < reader.get(middle):\n",
    "                right = middle - 1\n",
    "            else:\n",
    "                left = middle + 1\n",
    "                \n",
    "        return -1\n",
    "        \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        l=0\n",
    "        r=10**4\n",
    "\n",
    "        while l<=r:\n",
    "            mid=(l+r)>>1\n",
    "            t=reader.get(mid)\n",
    "\n",
    "            if t==target:\n",
    "                return mid\n",
    "            elif t<target:\n",
    "                l=mid+1\n",
    "            else:\n",
    "                r=mid-1\n",
    "\n",
    "        return -1\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        left, right = 0, 1\n",
    "        while reader.get(right) != (2**31 - 1) and reader.get(right) < target:\n",
    "            left = right\n",
    "            right  *= 2\n",
    "        \n",
    "        while left <= right:\n",
    "            mid = left + (right - left) // 2\n",
    "            if reader.get(mid) < target:\n",
    "                left = mid + 1\n",
    "            elif reader.get(mid) > target:\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                return mid\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        l, r = 0, 10000-1\n",
    "        constant = pow(2, 31) - 1\n",
    "        while l <= r:\n",
    "            mid = (l + r) // 2\n",
    "            if reader.get(mid) == constant:\n",
    "                r = mid - 1\n",
    "            else:\n",
    "                l = mid + 1\n",
    "        right_boundary = r\n",
    "        l, r = 0, right_boundary\n",
    "        while l <= r:\n",
    "            mid = (l + r) // 2\n",
    "            if reader.get(mid) == target:\n",
    "                return mid\n",
    "            elif reader.get(mid) < target:\n",
    "                l = mid + 1\n",
    "            else:\n",
    "                r = mid - 1\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        l = 0\n",
    "        r = 10**4 - 1  # 虽然数组长度未知但是其长度范围却限定了，初始化为其数组长度最大值-1\n",
    "        while l <= r:  # 区间不为空\n",
    "            mid = (l + r) // 2\n",
    "            # 不满足条件一：\n",
    "            #   如果mid超出数组边界，则返回值一定大于target最大值\n",
    "            #   如果没超出边界仅仅是mid位置值与target不相等\n",
    "            if reader.get(mid) == target:  # 条件一\n",
    "                return mid\n",
    "            elif reader.get(mid) == 2**32 - 1:  # 如果超出了边界，更新右指针，缩小右边界\n",
    "                r = mid - 1\n",
    "            else:  # 如果没超出边界只是mid值与target不符（只有大于小于两种情况），常规二分\n",
    "                if reader.get(mid) > target:\n",
    "                    r = mid - 1\n",
    "                else:\n",
    "                    l = mid + 1\n",
    "        return -1  # 二分循环结束，数组找不到target，返回-1\n",
    "        \n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        cmin=0\n",
    "        cmax=10**4\n",
    "        \n",
    "        while cmin<=cmax:\n",
    "            mid=(cmin+cmax)//2\n",
    "            t=reader.get(mid)\n",
    "            if t==target :\n",
    "                return mid\n",
    "            elif t>target:\n",
    "                cmax=mid-1\n",
    "            else:\n",
    "                cmin=mid+1\n",
    "        return -1\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "\n",
    "        l, r = 0, 10 ** 4 - 1\n",
    "\n",
    "        while l < r:\n",
    "\n",
    "            mid = (l + r ) // 2\n",
    "\n",
    "            if reader.get(mid) == 2 ** 31 - 1:\n",
    "                r = mid - 1\n",
    "            elif reader.get(mid) == target:\n",
    "                return mid\n",
    "            elif reader.get(mid) < target:\n",
    "                l = mid + 1\n",
    "            else:\n",
    "                r = mid - 1\n",
    "        return -1 if reader.get(l) != target else l\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        \"\"\"\n",
    "        查找target在数组之中的位置\n",
    "        Args:\n",
    "            reader (ArrayReader): \n",
    "            target (int):\n",
    "        returns (int):\n",
    "        \"\"\"\n",
    "        #处理异常情况\n",
    "        if reader == None or target == None:\n",
    "            return -1 \n",
    "\n",
    "        #使用二分查找的方法, 在[0...10**4]之间查找\n",
    "        left, right = 0, 10**4\n",
    "        INT_MAX = 2**31 - 1\n",
    "\n",
    "        while left <= right:\n",
    "            mid = left + ((right - left) >> 1)\n",
    "            search_res = reader.get(mid)\n",
    "            #case1. 越界, right = mid - 1\n",
    "            if search_res == INT_MAX:\n",
    "                right = mid - 1\n",
    "            #case2. search_res == target, 直接返回mid\n",
    "            elif search_res == target:\n",
    "                return mid \n",
    "            #case3. search_res < target, left = mid + 1\n",
    "            elif search_res < target:\n",
    "                left = mid + 1 \n",
    "            #case4. search_res > target, right = mid - 1\n",
    "            else:\n",
    "                right= mid - 1\n",
    "\n",
    "        #return \n",
    "        return -1 \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        left = 0\n",
    "        right = 1\n",
    "        # 搜索边界值\n",
    "        while reader.get(right) < target:\n",
    "            left = right\n",
    "            right = right * 2\n",
    "\n",
    "        while left <= right:\n",
    "            midle = (left + right) // 2\n",
    "            if reader.get(midle) < target:\n",
    "                left = midle + 1\n",
    "            elif reader.get(midle) > target:\n",
    "                right = midle - 1\n",
    "            else:\n",
    "                return midle\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        i = 1\n",
    "        while reader.get(i) < target:\n",
    "            i <<= 1\n",
    "\n",
    "        left, right = i >> 1, i\n",
    "\n",
    "        while left <= right:\n",
    "            mid = left + (right - left) // 2\n",
    "            if reader.get(mid) == target:\n",
    "                return mid\n",
    "            elif reader.get(mid) > target:\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                left = mid + 1\n",
    "        \n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        \n",
    "        left, right = 0, 10000\n",
    "        while left <= right:\n",
    "            mid = left + (right - left) // 2\n",
    "            cur = reader.get(mid)\n",
    "\n",
    "            if cur == target:\n",
    "                return mid \n",
    "            elif cur == 2**31 - 1 or cur > target:\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                left = mid + 1\n",
    "        \n",
    "        return -1 \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        start, end = 0, 1\n",
    "\n",
    "        # find the right range which contains target value\n",
    "        while reader.get(end) < target:\n",
    "            end = (end << 1)\n",
    "        \n",
    "        # binary search\n",
    "        while start <= end:\n",
    "            mid = start + ((end - start) >> 1)\n",
    "\n",
    "            if reader.get(mid) == target:\n",
    "                return mid\n",
    "            elif reader.get(mid) < target:\n",
    "                start = mid + 1\n",
    "            else:\n",
    "                end = mid - 1\n",
    "        \n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader, target):\n",
    "        \"\"\"\n",
    "        :type reader: ArrayReader\n",
    "        :type target: int\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        left, right = 0, 20000\n",
    "        while left < right:\n",
    "            mid = (left + right) //2\n",
    "            if reader.get(mid) >= target:\n",
    "                right = mid\n",
    "            else:\n",
    "                left = mid + 1\n",
    "        return left if reader.get(left) == target else -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        # find the boundry of array\n",
    "        # binary, iter the length from 0, 1, 2, 4, ... 2 ** n\n",
    "        startLen = 1\n",
    "        endLen = 2\n",
    "        errorNum = 2 ** 31 - 1\n",
    "        while 1:\n",
    "            if reader.get(endLen - 1) == errorNum:\n",
    "                break\n",
    "            else:\n",
    "                startLen = endLen\n",
    "                endLen *= 2\n",
    "        \n",
    "        actualLen = startLen\n",
    "        while startLen <= endLen:\n",
    "            mid = (startLen + endLen) // 2\n",
    "            if reader.get(mid - 1) == errorNum:\n",
    "                endLen = mid - 1\n",
    "            else:\n",
    "                actualLen = mid\n",
    "                startLen = mid + 1\n",
    "        \n",
    "        # find the index for target\n",
    "        left = 0\n",
    "        right = actualLen - 1\n",
    "        while left <= right:\n",
    "            mid = (left + right) // 2\n",
    "            if reader.get(mid) == target:\n",
    "                return mid\n",
    "            elif reader.get(mid) > target:\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                left = mid + 1\n",
    "        \n",
    "        return -1\n",
    "\n",
    "        \n",
    "        \n",
    "\n",
    "\n",
    "        \n",
    "\n",
    "\n",
    "\n",
    "        \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        l, r = 0, 10**4-1\n",
    "        while l <= r:\n",
    "            m = (l+r) // 2\n",
    "            if reader.get(m) ==  2**31-1:\n",
    "                r = m - 1\n",
    "            else:\n",
    "                if reader.get(m) == target:\n",
    "                    return m\n",
    "                elif reader.get(m) < target:\n",
    "                    l = m + 1\n",
    "                else:\n",
    "                    r = m - 1\n",
    "        return -1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        left, right = 0, 1\n",
    "        \n",
    "        while reader.get(right) < target and reader.get(right) != 2**31 - 1:\n",
    "            left = right\n",
    "            right <<= 1\n",
    "        \n",
    "        \n",
    "        while left <= right:\n",
    "            mid = left + (right - left) // 2\n",
    "            if reader.get(mid) == target:\n",
    "                return mid\n",
    "            elif reader.get(mid) < target:\n",
    "                left = mid + 1\n",
    "            else:\n",
    "                right = mid - 1\n",
    "        \n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "ceil = 2**31 - 1\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        # 按照数组最大的可能性设置左右边界\n",
    "        left = 0\n",
    "        right = 20000\n",
    "        while left < right:\n",
    "            mid = (left + right + 1) >> 1 # 右中位数\n",
    "            if reader.get(mid) == 2147483647: # 如果越界，则右边界收缩\n",
    "                right = mid - 1\n",
    "            elif reader.get(mid) > target: # 如果大于目标值，则右边界收缩\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                left = mid\n",
    "        return left if reader.get(left) == target else -1 # 返回结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        left, right = 0, 1\n",
    "        if reader.get(0) == target:\n",
    "            return 0\n",
    "        while reader.get(right) < target and reader.get(right) != 2147483647:\n",
    "            left = right\n",
    "            right *= 2\n",
    "        while left <= right:\n",
    "            mid = left + (right - left)//2\n",
    "            num = reader.get(mid)\n",
    "            if num == target:\n",
    "                return mid\n",
    "            elif num < target:\n",
    "                left = mid + 1\n",
    "            else:\n",
    "                right = mid - 1\n",
    "            \n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        l = 0\n",
    "        if reader.get(0) == target:\n",
    "            return 0\n",
    "        r = 1\n",
    "        while reader.get(r) != 2**31-1:\n",
    "            if reader.get(r) == target:\n",
    "                return r\n",
    "            r = r*2\n",
    "        while l <= r:\n",
    "            mid = l + (r-l)//2\n",
    "            val = reader.get(mid)\n",
    "            if val == target:\n",
    "                return mid\n",
    "            elif val < target:\n",
    "                l = mid + 1\n",
    "            else:\n",
    "                r = mid - 1\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        #这是一道非常牛的题目，注意它查找边界的思路\n",
    "        if reader.get(0) == target:\n",
    "            return 0\n",
    "\n",
    "        #下面这里在查找边界\n",
    "        left = 0\n",
    "        right = 1\n",
    "        while reader.get(right) < target:\n",
    "            left = right \n",
    "            right *= 2\n",
    "        \n",
    "        while left <= right:\n",
    "           mid = (right + left)//2\n",
    "           num = reader.get(mid)\n",
    "           \n",
    "           if num == target:\n",
    "               return mid\n",
    "\n",
    "           if num > target:\n",
    "               right = mid - 1\n",
    "\n",
    "           else:\n",
    "               left = mid + 1\n",
    "       \n",
    "        # 没有目标元素\n",
    "        return -1\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        left, right = 0, 1\n",
    "        while reader.get(right) < target and reader.get(right) != 2147483647:\n",
    "            left = right\n",
    "            right *= 2\n",
    "        while left <= right:\n",
    "            mid = left + (right - left)//2\n",
    "            if reader.get(mid) < target:\n",
    "                left = mid + 1\n",
    "            elif reader.get(mid) > target:\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                return mid\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        #交互调用访问\n",
    "        cmin,cmax=0,10**4\n",
    "\n",
    "        while cmin<=cmax:\n",
    "            mid=(cmin+cmax)//2\n",
    "            t=reader.get(mid)\n",
    "            if t==target:\n",
    "                return mid\n",
    "            elif t> target:\n",
    "                cmax=mid-1\n",
    "            else:\n",
    "                cmin=mid+1\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        left,right=-1,10**4+1\n",
    "        while left+1<right:\n",
    "            mid=(left+right)//2\n",
    "            if reader.get(mid)<target:\n",
    "                left=mid\n",
    "            else:\n",
    "                right=mid\n",
    "        return right if reader.get(right)==target else -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        left = 0\n",
    "        right = 10 ** 4 -1\n",
    "\n",
    "        while left <= right:\n",
    "            mid = (left + right) // 2\n",
    "            if reader.get(mid) < target:\n",
    "                left = mid + 1\n",
    "            elif reader.get(mid) > target:\n",
    "                right = mid - 1\n",
    "            elif reader.get(mid) == target:\n",
    "                return mid\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        cmin=0\n",
    "        cmax=10**4\n",
    "        \n",
    "        while cmin<=cmax:\n",
    "            mid=(cmin+cmax)//2\n",
    "            t=reader.get(mid)\n",
    "            if t==target :\n",
    "                return mid\n",
    "            elif t>target:\n",
    "                cmax=mid-1\n",
    "            else:\n",
    "                cmin=mid+1\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        left, right = 0, 1\n",
    "        while reader.get(right) != (2**31 - 1) and reader.get(right) < target:\n",
    "            left = right\n",
    "            right  *= 2\n",
    "        \n",
    "        while left <= right:\n",
    "            mid = left + (right - left) // 2\n",
    "            if reader.get(mid) < target:\n",
    "                left = mid + 1\n",
    "            elif reader.get(mid) > target:\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                return mid\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        if reader.get(0) == target:\n",
    "            return 0\n",
    "\n",
    "        l, r = 0, 1\n",
    "        while reader.get(r) < target:\n",
    "            r *= 2\n",
    "\n",
    "        while l <= r:\n",
    "            m = l + (r - l) // 2\n",
    "            n = reader.get(m)\n",
    "            if n == target:\n",
    "                return m\n",
    "            elif n > target:\n",
    "                r = m - 1\n",
    "            else:\n",
    "                l = m + 1\n",
    "\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        left, right = 0, 10**4 - 1\n",
    "        while left <= right:\n",
    "            mid = (right - left) // 2 + left\n",
    "            if reader.get(mid) == target:\n",
    "                return mid\n",
    "            elif reader.get(mid) > target:\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                left = mid + 1\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        # 与普通二分法没有差别，只是将reader右侧不存在的位置全部视作用2**31-1填充\n",
    "        if reader.get(0) > target: return -1\n",
    "        # 生序意味着如果存在target，一定位于第 0 位到第 target - reader.get(0)] 位之间\n",
    "        left, right = 0, target - reader.get(0)\n",
    "        while left <= right:\n",
    "            mid = (right + left) // 2\n",
    "            if reader.get(mid) == target:\n",
    "                return mid\n",
    "            elif reader.get(mid) > target:\n",
    "                right = mid - 1\n",
    "            else: left = mid + 1\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        #确定上下界情况\n",
    "        left,right=0,10**4     \n",
    "        while left<=right:\n",
    "            mid=left+(right-left)//2\n",
    "            if reader.get(mid) < target:\n",
    "                left=mid+1\n",
    "            elif reader.get(mid) >target:\n",
    "                right=mid-1\n",
    "            elif reader.get(mid) ==target:\n",
    "                return mid\n",
    "        return -1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        if not reader: return -1\n",
    "        \n",
    "        left, right = 0, 1\n",
    "        while reader.get(right) <= target: right = right << 1\n",
    "        while left + 1 < right:\n",
    "            mid = left + (right - left) // 2\n",
    "            if reader.get(mid) <= target: left = mid\n",
    "            else: right = mid\n",
    "        if reader.get(left) == target: return left\n",
    "        if reader.get(right) == target: return right\n",
    "        return -1\n",
    "         "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        if reader.get(0)==2**31-1 or reader.get(0)>target:\n",
    "            return -1\n",
    "        if reader.get(0)==target:\n",
    "            return 0\n",
    "        l,r = 0,1\n",
    "        while reader.get(r)<=target:\n",
    "            if reader.get(r)==target:\n",
    "                return r \n",
    "            l = r \n",
    "            r = r*2\n",
    "        while l<r:\n",
    "            mid = (l + r)//2\n",
    "            if reader.get(mid)==target:\n",
    "                return mid\n",
    "            elif reader.get(mid)>target:\n",
    "                r = mid\n",
    "            else:\n",
    "                l = mid+1\n",
    "        return -1\n",
    "        \n",
    "            \n",
    "\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        cmin=0\n",
    "        cmax=10**4\n",
    "        \n",
    "        while cmin<=cmax:\n",
    "            mid=(cmin+cmax)//2\n",
    "            t=reader.get(mid)\n",
    "            if t==target :\n",
    "                return mid\n",
    "            elif t>target:\n",
    "                cmax=mid-1\n",
    "            else:\n",
    "                cmin=mid+1\n",
    "        return -1\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        rangeTotal = 1\n",
    "        while reader.get(rangeTotal - 1) < target:\n",
    "            rangeTotal *= 2\n",
    "\n",
    "        # start, end = 0, rangeTotal - 1\n",
    "        start, end = rangeTotal // 2, rangeTotal - 1\n",
    "        while start + 1 < end:\n",
    "            mid = start + (end - start) // 2\n",
    "            if reader.get(mid) < target:\n",
    "                start = mid\n",
    "            else:\n",
    "                end = mid\n",
    "        \n",
    "        if reader.get(start) == target:\n",
    "            return start\n",
    "        if reader.get(end) == target:\n",
    "            return end\n",
    "\n",
    "        return -1  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        cmin=0\n",
    "        cmax=10**4\n",
    "        \n",
    "        while cmin<=cmax:\n",
    "            mid=(cmin+cmax)>>1\n",
    "            t=reader.get(mid)\n",
    "            if t==target :\n",
    "                return mid\n",
    "            elif t>target:\n",
    "                cmax=mid-1\n",
    "            else:\n",
    "                cmin=mid+1\n",
    "        return -1\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        left,right=0,1\n",
    "        while reader.get(right)<target:\n",
    "            left=right\n",
    "            right<<=1\n",
    "        while left<=right:\n",
    "            mid=left+((right-left)>>1)\n",
    "            if reader.get(mid)==target:\n",
    "                return mid\n",
    "            elif reader.get(mid)>target:\n",
    "                right=mid-1\n",
    "            else:\n",
    "                left=mid+1\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        #i: [0,2^31 - 1]\n",
    "        l,r = 0,2**31 - 1\n",
    "        while l < r: \n",
    "            m = (l + r) // 2\n",
    "            if reader.get(m) == target:\n",
    "                return m\n",
    "            if reader.get(m) > target:\n",
    "                r = m \n",
    "            else :\n",
    "                l = m + 1\n",
    "        return -1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        # find the boundry of array\n",
    "        # binary, iter the length from 0, 1, 2, 4, ... 2 ** n\n",
    "        startLen = 1\n",
    "        endLen = 2\n",
    "        errorNum = 2 ** 31 - 1\n",
    "        while 1:\n",
    "            if reader.get(endLen - 1) == errorNum:\n",
    "                break\n",
    "            else:\n",
    "                startLen = endLen\n",
    "                endLen *= 2\n",
    "        '''\n",
    "        actualLen = startLen\n",
    "        while startLen <= endLen:\n",
    "            mid = (startLen + endLen) // 2\n",
    "            if reader.get(mid - 1) == errorNum:\n",
    "                endLen = mid - 1\n",
    "            else:\n",
    "                actualLen = mid\n",
    "                startLen = mid + 1\n",
    "        '''\n",
    "        \n",
    "        # find the index for target\n",
    "        left = 0\n",
    "        right = endLen - 1\n",
    "        while left <= right:\n",
    "            mid = (left + right) // 2\n",
    "            if reader.get(mid) == target:\n",
    "                return mid\n",
    "            elif reader.get(mid) > target:\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                left = mid + 1\n",
    "        \n",
    "        return -1\n",
    "\n",
    "        \n",
    "        \n",
    "\n",
    "\n",
    "        \n",
    "\n",
    "\n",
    "\n",
    "        \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        left, right = 0, 10 ** 4 + 1\n",
    "        while left <= right:\n",
    "            mid = left + (right - left) // 2\n",
    "            if reader.get(mid) != -1:\n",
    "                left = mid + 1\n",
    "            else:\n",
    "                right = mid - 1\n",
    "        \n",
    "        l, r = 0, left \n",
    "        while l <= r:\n",
    "            mid = l + (r - l) // 2\n",
    "            if reader.get(mid) < target:\n",
    "                l = mid + 1\n",
    "            elif reader.get(mid) > target:\n",
    "                r = mid - 1\n",
    "            else:\n",
    "                return mid \n",
    "        return -1\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        left,right=-1,10**4+1\n",
    "        while left+1<right:\n",
    "            mid=(left+right)//2\n",
    "            if reader.get(mid)<target:\n",
    "                left=mid\n",
    "            else:\n",
    "                right=mid\n",
    "        return right if reader.get(right)==target else -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        l, r = 0, 10000-1\n",
    "        constant = pow(2, 31) - 1\n",
    "        while l <= r:\n",
    "            mid = (l + r) // 2\n",
    "            if reader.get(mid) == constant:\n",
    "                r = mid - 1\n",
    "            else:\n",
    "                l = mid + 1\n",
    "        right_boundary = r\n",
    "        l, r = 0, right_boundary\n",
    "        while l <= r:\n",
    "            mid = (l + r) // 2\n",
    "            if reader.get(mid) == target:\n",
    "                return mid\n",
    "            elif reader.get(mid) < target:\n",
    "                l = mid + 1\n",
    "            else:\n",
    "                r = mid - 1\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        max = (2*31)-1\n",
    "        l, r = 0,1\n",
    "        cnt = 0\n",
    "        #nums = ArrayReader()\n",
    "        while l <= r :\n",
    "            mid = l + (r-l)//2\n",
    "            if reader.get(mid) == target:\n",
    "                return mid\n",
    "            elif reader.get(mid) == max:\n",
    "                if cnt == 1:\n",
    "                    return -1 \n",
    "                else:\n",
    "                    r=mid-1\n",
    "                    cnt =1   \n",
    "            elif reader.get(mid) < target:\n",
    "                l = mid +1\n",
    "                r = r*2\n",
    "            elif reader.get(mid) >  target:\n",
    "                r = mid-1 \n",
    "        return -1 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        arrLen =-1\n",
    "        l,r = 0, 2**31-1\n",
    "        \n",
    "        while l<r:\n",
    "            mid = (l+r)//2\n",
    "            val = reader.get(mid)\n",
    "            if val ==(2**31-1):\n",
    "                r = mid\n",
    "            else:\n",
    "                l = mid+1\n",
    "        arrLen = l\n",
    "        l,r = 0, arrLen-1\n",
    "        ans=-1\n",
    "        while l<=r:\n",
    "            mid = (l+r)//2\n",
    "            val = reader.get(mid)\n",
    "            if val ==target:\n",
    "                ans = mid\n",
    "                break\n",
    "            elif val >target:\n",
    "                r = mid-1\n",
    "            else:\n",
    "                l = mid+1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        l, r = 0, 10**4\n",
    "        while l <= r:\n",
    "            #mid = l + int((r - l)/2)\n",
    "            #\n",
    "            mid = (l+r)//2\n",
    "            res = reader.get(mid)\n",
    "            if res == target:\n",
    "                return mid\n",
    "            elif res < target:\n",
    "                l = mid + 1\n",
    "            else:\n",
    "                r = mid - 1\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        if reader.get(0) == target:\n",
    "            return 0 \n",
    "        \n",
    "        #max = (2*31)-1\n",
    "        l, r = 0,1\n",
    "        #扩张搜索边界\n",
    "        while reader.get(r) <target:\n",
    "            l = r\n",
    "            r<<= 1\n",
    "\n",
    "        while l <= r :\n",
    "            mid = l + (r-l)//2\n",
    "            num = reader.get(mid)\n",
    "            if num == target:\n",
    "                return mid\n",
    "            # elif reader.get(mid) == max:\n",
    "            #         r=mid-1  \n",
    "            elif num < target:\n",
    "                l = mid +1\n",
    "                # r = r*2\n",
    "            elif num >  target:\n",
    "                r = mid-1 \n",
    "        return -1 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        l=0\n",
    "        r=9999\n",
    "        k=0\n",
    "        while l<=r:#找到右边界\n",
    "            m=l+(r-l)//2\n",
    "            if r-l==1 and reader.get(l)<=10000 and reader.get(r)>10000:\n",
    "                k=l\n",
    "                break\n",
    "            if reader.get(m)<=10000:\n",
    "                l=m+1\n",
    "                if reader.get(l)>10000:\n",
    "                    k=m\n",
    "                    break\n",
    "            else:\n",
    "                r=m-1\n",
    "                if reader.get(r)<=10000:\n",
    "                    k=r\n",
    "                    break\n",
    "        #print(k,l,r)\n",
    "        l=0\n",
    "        r=k\n",
    "        while l<=r:#定位target\n",
    "            m=l+(r-l)//2\n",
    "            p=reader.get(m)\n",
    "            if p==target:\n",
    "                return m\n",
    "            elif p>target:\n",
    "                r=m-1\n",
    "            else:\n",
    "                l=m+1\n",
    "        return -1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        if not reader: return -1\n",
    "        \n",
    "        left, right = 0, 1\n",
    "        while reader.get(right) <= target: right = right << 1\n",
    "        while left + 1 < right:\n",
    "            mid = left + (right - left) // 2\n",
    "            if reader.get(mid) <= target: left = mid\n",
    "            else: right = mid\n",
    "        if reader.get(left) == target: return left\n",
    "        if reader.get(right) == target: return right\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        left, right = 0, 1\n",
    "        while reader.get(right) != (2**31 - 1) and reader.get(right) < target:\n",
    "            left = right\n",
    "            right  *= 2\n",
    "        \n",
    "        while left <= right:\n",
    "            mid = left + (right - left) // 2\n",
    "            if reader.get(mid) < target:\n",
    "                left = mid + 1\n",
    "            elif reader.get(mid) > target:\n",
    "                right = mid - 1\n",
    "            else:\n",
    "                return mid\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        if not reader: return -1\n",
    "    \n",
    "        left, right = 0, 1\n",
    "        while reader.get(right) <= target: right = right << 1\n",
    "        while left + 1 < right:\n",
    "            mid = (left + right) // 2\n",
    "            if reader.get(mid) <= target: left = mid\n",
    "            else: right = mid\n",
    "        if reader.get(left) == target: return left\n",
    "        if reader.get(right) == target: return right\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        left, right = 0, 1\n",
    "        while reader.get(right) < target:\n",
    "            left = right\n",
    "            right *= 2\n",
    "        while left < right:\n",
    "            mid = (left + right) // 2\n",
    "            if reader.get(mid) == target:\n",
    "                return mid\n",
    "            elif reader.get(mid) > target:\n",
    "                right = mid\n",
    "            else:\n",
    "                left = mid + 1\n",
    "        return -1 if reader.get(left) != target else left"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        l = 0\n",
    "        if reader.get(0) == target:\n",
    "            return 0\n",
    "        r = 1\n",
    "        while reader.get(r) != 2**31-1 and reader.get(r)<=target:\n",
    "            if reader.get(r) == target:\n",
    "                return r\n",
    "            r = r*2\n",
    "        while l <= r:\n",
    "            mid = l + (r-l)//2\n",
    "            val = reader.get(mid)\n",
    "            if val == target:\n",
    "                return mid\n",
    "            elif val < target:\n",
    "                l = mid + 1\n",
    "            else:\n",
    "                r = mid - 1\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        #解题思路：\n",
    "        #二分查找\n",
    "\n",
    "        l,r = 0,10 ** 4 -1\n",
    "        while l <= r:\n",
    "            # print(l,r)\n",
    "            mid = (l + r) // 2\n",
    "            if reader.get(mid) == target:\n",
    "                return mid\n",
    "            elif reader.get(mid) < target:\n",
    "                l = mid + 1\n",
    "            else:\n",
    "                r = mid - 1\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        if not reader: return -1\n",
    "        \n",
    "        left, right = 0, 1\n",
    "        while reader.get(right) <= target: right = right << 1\n",
    "        while left + 1 < right:\n",
    "            mid = (left + right) // 2\n",
    "            if (reader.get(mid) <= target):\n",
    "                left = mid\n",
    "            else:\n",
    "                right = mid\n",
    "        if (reader.get(left) == target): return left\n",
    "        if (reader.get(right) == target): return right\n",
    "        return -1\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        if reader.get(0) == target:\n",
    "            return 0\n",
    "\n",
    "        l, r = 0, 1\n",
    "        while reader.get(r) < target:\n",
    "            l = r\n",
    "            r *= 2\n",
    "\n",
    "        if reader.get(r) == target:\n",
    "            return r\n",
    "\n",
    "        while l <= r:\n",
    "            m = l + (r - l) // 2\n",
    "            n = reader.get(m)\n",
    "            if n == target:\n",
    "                return m\n",
    "            elif n > target:\n",
    "                r = m - 1\n",
    "            else:\n",
    "                l = m + 1\n",
    "\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        l, r = 0, 10000-1\n",
    "        constant = pow(2, 31) - 1\n",
    "        while l <= r:\n",
    "            mid = (l + r) >> 1\n",
    "            if reader.get(mid) == constant:\n",
    "                r = mid - 1\n",
    "            else:\n",
    "                l = mid + 1\n",
    "        right_boundary = r\n",
    "        l, r = 0, right_boundary\n",
    "        while l <= r:\n",
    "            mid = (l + r) >> 1\n",
    "            if reader.get(mid) == target:\n",
    "                return mid\n",
    "            elif reader.get(mid) < target:\n",
    "                l = mid + 1\n",
    "            else:\n",
    "                r = mid - 1\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "# class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        if reader.get(0) == target:\n",
    "            return 0\n",
    "        left, right = 0, 1\n",
    "        while reader.get(right) < target:\n",
    "            right <<= 1\n",
    "        res = -1\n",
    "        while left <= right:\n",
    "            mid = (left + right) >> 1\n",
    "            if reader.get(mid) <= target:\n",
    "                res = mid\n",
    "                left = mid + 1\n",
    "            else:\n",
    "                right = mid - 1\n",
    "        if reader.get(res) == target:\n",
    "            return res\n",
    "        return -1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        L, R = 0, 20000\n",
    "        while L < R:\n",
    "            mid = (L + R) // 2\n",
    "            if target <= reader.get(mid):\n",
    "                R = mid\n",
    "            else:\n",
    "                L = mid + 1     #二分查找框架--符合条件的最左端\n",
    "        \n",
    "        return L if reader.get(L) == target else -1\n",
    "\n",
    "# 作者：HanXin\n",
    "# 链接：https://leetcode.cn/problems/search-in-a-sorted-array-of-unknown-size/solutions/704516/c-python3-er-fen-cha-zhao-kuang-jia-fu-h-xd82/\n",
    "# 来源：力扣（LeetCode）\n",
    "# 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        l, r = 0, 1\n",
    "        while reader.get(r) < target:\n",
    "            l = r\n",
    "            r *= 2\n",
    "        \n",
    "        while l <= r:\n",
    "            mid = l + (r-l)//2\n",
    "            if reader.get(mid) == target:\n",
    "                return mid\n",
    "            elif reader.get(mid) < target:\n",
    "                l = mid + 1\n",
    "            else:\n",
    "                r = mid - 1\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        start = 0\n",
    "        end = 1\n",
    "        while start<end:\n",
    "            temp = reader.get(end-1)\n",
    "            if temp == target:\n",
    "                return end-1\n",
    "            if temp < target:\n",
    "                start = end\n",
    "                end = 2*end\n",
    "            if temp > target:\n",
    "                end = (start+end)//2\n",
    "        if reader.get(end-1) == target:\n",
    "            return start\n",
    "        else:\n",
    "            return -1\n",
    "\n",
    "        print(temp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        end=1\n",
    "        while reader.get(end) < target:\n",
    "            end = (end << 1)\n",
    "        #print(k,l,r)\n",
    "        l=0\n",
    "        r=end\n",
    "        while l<=r:#定位target\n",
    "            m=l+(r-l)//2\n",
    "            p=reader.get(m)\n",
    "            if p==target:\n",
    "                return m\n",
    "            elif p>target:\n",
    "                r=m-1\n",
    "            else:\n",
    "                l=m+1\n",
    "        return -1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# \"\"\"\n",
    "# This is ArrayReader's API interface.\n",
    "# You should not implement it, or speculate about its implementation\n",
    "# \"\"\"\n",
    "#class ArrayReader:\n",
    "#    def get(self, index: int) -> int:\n",
    "\n",
    "class Solution:\n",
    "    def search(self, reader: 'ArrayReader', target: int) -> int:\n",
    "        start, end = 0, 1\n",
    "        while True:\n",
    "            if reader.get(end) < target:\n",
    "                end = end * 2\n",
    "            else:\n",
    "                break\n",
    "        while start < end:\n",
    "            mid = start + (end - start) // 2\n",
    "            if reader.get(mid) == target:\n",
    "                return mid\n",
    "            elif reader.get(mid) < target:\n",
    "                start = mid + 1\n",
    "            else:\n",
    "                end = mid - 1\n",
    "        if reader.get(start) == target:\n",
    "            return start\n",
    "        return -1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> bool:\n",
    "        \n",
    "\n",
    "        n = len(nums)\n",
    "        l, r = 0, n - 1\n",
    "        while l <= r:\n",
    "            mid = (l + r) // 2\n",
    "            if nums[mid] == target:\n",
    "                return True\n",
    "            elif nums[mid] < target:\n",
    "                if nums[mid] > nums[l]:\n",
    "                    l = mid + 1\n",
    "                elif nums[mid] == nums[l]:\n",
    "                    if nums[r] == nums[l]:\n",
    "                        k = mid\n",
    "                        while k > l and nums[k] == nums[mid]:\n",
    "                            k -= 1\n",
    "                        if k == l:\n",
    "                            l = mid + 1\n",
    "                        else:\n",
    "                            r = k\n",
    "                    else:\n",
    "                        l = mid + 1\n",
    "                else: # mid < l                  \n",
    "                    if nums[r] >= target:\n",
    "                        l = mid + 1\n",
    "                    else:\n",
    "                        r = mid - 1\n",
    "            else: # mid > target\n",
    "                if nums[mid] > nums[l]:\n",
    "                    if nums[l] <= target:\n",
    "                        r = mid - 1\n",
    "                    else:\n",
    "                        l = mid + 1\n",
    "                elif nums[mid] == nums[l]:\n",
    "                    if nums[r] == nums[l]:\n",
    "                        k = mid\n",
    "                        while k > l and nums[k] == nums[mid]:\n",
    "                            k -= 1\n",
    "                        if k == l:\n",
    "                            l = mid + 1\n",
    "                        else:\n",
    "                            r = k\n",
    "                    else:\n",
    "                        l = mid + 1\n",
    "                else: # mid < l\n",
    "                    r = mid - 1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        if not nums:\n",
    "            return False\n",
    "        left, right = 0, len(nums)-1\n",
    "        while left <= right:\n",
    "            if (left != right and nums[left]==nums[right]):\n",
    "                left += 1\n",
    "                while nums[left] == nums[left-1] and left < len(nums)-1:\n",
    "                    left += 1\n",
    "                while nums[right] == nums[right-1] and right > 0:\n",
    "                    right -= 1\n",
    "            mid = (left+right) // 2\n",
    "            if nums[mid] == target:\n",
    "                return True\n",
    "            if nums[mid] > nums[right]:  # 左有序\n",
    "                if nums[mid] > target and nums[left] <= target:\n",
    "                    right = mid - 1\n",
    "                else:\n",
    "                    left = mid + 1\n",
    "            else:  # 右有序\n",
    "                if nums[mid] < target and nums[right] >= target:\n",
    "                    left = mid + 1\n",
    "                else:\n",
    "                    right = mid -1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: 'List[int]', target: 'int') -> 'bool':\n",
    "        l, r = 0, len(nums)-1\n",
    "        while l <= r:\n",
    "            mid = (l + r) // 2\n",
    "            if nums[mid] == target:\n",
    "                return True\n",
    "            while l < mid and nums[l] == nums[mid]: \n",
    "                l += 1\n",
    "            if nums[l] <= nums[mid]:\n",
    "                if nums[l] <= target < nums[mid]:\n",
    "                    r = mid - 1\n",
    "                else:\n",
    "                    l = mid + 1\n",
    "            else:\n",
    "                if nums[mid] < target and target <= nums[r]:\n",
    "                    l = mid + 1\n",
    "                else:\n",
    "                    r = mid - 1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        return target in set(nums)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums, target):\n",
    "        def second_search(left,right):\n",
    "            while left <= right:\n",
    "                mid = (left+right)//2\n",
    "                if nums[mid] == target:\n",
    "                    return True\n",
    "                elif nums[mid] > target:\n",
    "                    right = mid-1\n",
    "                else:\n",
    "                    left = mid+1\n",
    "            return False\n",
    "\n",
    "        def rotate_bin_search(left, right):\n",
    "            if right-left < 5:\n",
    "                return target in nums[left:right+1]\n",
    "            mid = (left + right) // 2\n",
    "            if nums[left] < nums[mid]:\n",
    "                if nums[left] <= target <= nums[mid]:\n",
    "                    return second_search(left, mid)\n",
    "                else:\n",
    "                    return rotate_bin_search(mid+1, right)\n",
    "            elif nums[left] == nums[mid]:\n",
    "                if nums[left] == target:\n",
    "                    return True\n",
    "                if len(set(nums[left:mid])) == 1:\n",
    "                    return rotate_bin_search(mid+1, right)\n",
    "                return rotate_bin_search(left, mid-1)\n",
    "            else:\n",
    "                if nums[mid] <= target <= nums[right]:\n",
    "                    return second_search(mid, right)\n",
    "                else:\n",
    "                    return rotate_bin_search(left, mid-1)\n",
    "\n",
    "        return rotate_bin_search(0, len(nums) - 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums, target):\n",
    "        \"\"\"\n",
    "        81. Search in Rotated Sorted Array II\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        p,r=0,len(nums)-1\n",
    "        while p<=r:\n",
    "            print(p,r)\n",
    "            q=int((p+r)/2)\n",
    "            if target==nums[q]:\n",
    "                return True\n",
    "\n",
    "            if nums[p]<nums[q]:\n",
    "                if target>= nums[p] and target<=nums[q-1]:\n",
    "                    r=q-1\n",
    "                else:\n",
    "                    p=q+1\n",
    "            elif nums[p]==nums[q]:\n",
    "                if nums[p]==nums[r] or nums[p]>nums[r]:\n",
    "                    p+=1\n",
    "                else:\n",
    "                    p=q+1\n",
    "            else:\n",
    "                if target>=nums[q+1] and target<=nums[r]:\n",
    "                    p=q+1\n",
    "                else:\n",
    "                    r=q-1\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        if not nums:\n",
    "            return False\n",
    "        i,j=0,len(nums)-1\n",
    "        self.ans=False\n",
    "        self.target=target\n",
    "        self.bisearch(0,j,nums)\n",
    "        return self.ans\n",
    "        \n",
    "    def bisearch(self,i,j,nums):\n",
    "        if i>j or self.ans:\n",
    "            return\n",
    "        if nums[i]==self.target or nums[j]==self.target:\n",
    "            self.ans=True\n",
    "            return\n",
    "        if nums[i]<nums[j]:\n",
    "            if nums[i]>self.target or nums[j]<self.target:\n",
    "                return\n",
    "            else:\n",
    "                mid=(i+j)//2\n",
    "                if nums[mid]>self.target:\n",
    "                    self.bisearch(i,j-1,nums)\n",
    "                elif nums[mid]<self.target:\n",
    "                    self.bisearch(mid+1,j,nums)\n",
    "                else:\n",
    "                    self.ans=True\n",
    "        else:\n",
    "            mid=(i+j)//2\n",
    "            if nums[mid]==self.target:\n",
    "                self.ans=True\n",
    "                return\n",
    "            self.bisearch(i,mid-1,nums)\n",
    "            self.bisearch(mid+1,j,nums)\n",
    "            \n",
    "            \n",
    "        \n",
    "                    \n",
    "                \n",
    "            \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: 'List[int]', target: 'int') -> 'bool':\n",
    "        left = 0;right = len(nums)-1\n",
    "        while left <= right:\n",
    "            mid = (left + right)//2\n",
    "            if nums[mid]  == target:\n",
    "                return True\n",
    "            elif nums[mid] >= nums[left]:\n",
    "                if nums[left]<= target <nums[mid]:\n",
    "                    right = mid - 1\n",
    "                else:\n",
    "                    left += 1\n",
    "            else:\n",
    "                if nums[mid]< target <= nums[right]:\n",
    "                    left = mid+1\n",
    "                else:\n",
    "                    right -= 1\n",
    "        return False\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, A: 'List[int]', target: 'int') -> 'bool':\n",
    "        if not A or target is None:\n",
    "            return False\n",
    "        \n",
    "        start, end = 0, len(A)-1\n",
    "        while start + 1 < end:\n",
    "            \n",
    "            while A[start] == A[start+1] and start + 1 < end:\n",
    "                start += 1\n",
    "            while A[end] == A[end-1] and start + 1 < end:\n",
    "                end -= 1\n",
    "                \n",
    "            mid = start + (end-start)//2\n",
    "            \n",
    "            if target in [A[start], A[mid], A[end]]:\n",
    "                return True\n",
    "            \n",
    "            if A[mid] < A[end]:\n",
    "                if A[mid] < target < A[end]:\n",
    "                    start = mid\n",
    "                else:\n",
    "                    end = mid\n",
    "            else:\n",
    "                if A[start] < target < A[mid]:\n",
    "                    end = mid\n",
    "                else:\n",
    "                    start = mid\n",
    "\n",
    "        return target in [A[start], A[end]]   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> bool:\n",
    "        if target in nums:\n",
    "            return(True)\n",
    "        else:\n",
    "            return(False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> bool:\n",
    "        n = len(nums)\n",
    "        l, r = 0, n-1\n",
    "        while r >= l:\n",
    "            mid = (r + l) // 2\n",
    "            if nums[mid] == target:\n",
    "                return True\n",
    "            if nums[mid] == nums[l]:\n",
    "                l += 1\n",
    "            elif nums[mid] > nums[l]:\n",
    "                if nums[mid] < target:\n",
    "                    l = mid + 1\n",
    "                else:\n",
    "                    if nums[l] > target:\n",
    "                        l = mid + 1\n",
    "                    else:\n",
    "                        r = mid - 1\n",
    "            else:\n",
    "                if nums[mid] < target:\n",
    "                    if nums[l] > target:\n",
    "                        l = mid + 1\n",
    "                    else:\n",
    "                        r = mid - 1\n",
    "                else:\n",
    "                    r = mid - 1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> bool:\n",
    "        if target in nums:\n",
    "            return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> bool:\n",
    "        if target in nums:\n",
    "            return True\n",
    "        else:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> bool:\n",
    "        if not nums:\n",
    "            return False\n",
    "        n=len(nums)\n",
    "        l=0\n",
    "        r=n-1\n",
    "        while l<=r:\n",
    "            mid=(r+l)//2\n",
    "            if nums[mid]==target:\n",
    "                return True\n",
    "            if nums[mid]>nums[l]:\n",
    "                if nums[l]<=target<=nums[mid]:\n",
    "                    r=mid-1\n",
    "                else:\n",
    "                    l=mid+1\n",
    "            elif nums[mid]==nums[l]:\n",
    "                l+=1\n",
    "            elif nums[mid]<nums[l]:\n",
    "                if nums[mid]<=target<=nums[r]:\n",
    "                    l=mid+1\n",
    "                else:\n",
    "                    r=mid-1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums, target):\n",
    "        left = 0\n",
    "        right = len(nums)-1\n",
    "        if right == -1:\n",
    "            return False\n",
    "        if right == 0:\n",
    "            if nums[0] == target:\n",
    "                return True\n",
    "            else:\n",
    "                return False\n",
    "\n",
    "        \n",
    "        while(left<right):\n",
    "            if nums[left] == target:\n",
    "                return True\n",
    "            elif nums[right] == target:\n",
    "                return True\n",
    "            mid = (left+right)//2\n",
    "            if nums[mid] == target:\n",
    "                return True\n",
    "            if nums[left] == nums[mid]:\n",
    "                left += 1\n",
    "                continue\n",
    "            \n",
    "            if nums[left]<nums[mid]:\n",
    "                # 左边有序,右边无序\n",
    "                if nums[left]<target<nums[mid]:\n",
    "                    right = mid - 1\n",
    "                \n",
    "                else:\n",
    "                    left = mid + 1\n",
    "            else:\n",
    "                if nums[mid]<target<nums[right]:\n",
    "                    left = mid + 1\n",
    "\n",
    "                else:\n",
    "                    right = mid - 1\n",
    "            \n",
    "        \n",
    "        return False\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> bool:\n",
    "        n = len(nums)\n",
    "        if n == 0:\n",
    "            return False\n",
    "        l, r = 0, n - 1\n",
    "        while l < r:\n",
    "            m = (l + r) // 2\n",
    "            if nums[m] == target:\n",
    "                return True\n",
    "\n",
    "            if nums[l] < nums[m]:\n",
    "                if nums[l] <= target < nums[m]:\n",
    "                    r = m - 1 \n",
    "                else:\n",
    "                    l = m + 1\n",
    "            elif nums[l] > nums[m]:\n",
    "                if nums[m] < target < nums[l]:\n",
    "                    l = m + 1\n",
    "                else:\n",
    "                    r = m - 1\n",
    "            else:\n",
    "                #nums[l] == nums[m]:\n",
    "                l += 1\n",
    "\n",
    "        if nums[l] == target:\n",
    "            return True\n",
    "        return False\n",
    "\n",
    "\n",
    "        \n",
    "        \n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> bool:\n",
    "        left=0\n",
    "        right=len(nums)-1\n",
    "        while left<=right:\n",
    "            print(left,right)\n",
    "            mid=(left+right)//2\n",
    "            if nums[left]==target:\n",
    "                return True\n",
    "            if nums[right]==target:\n",
    "                return True\n",
    "            if nums[mid]==target:\n",
    "                return True\n",
    "            if nums[left]<target<nums[mid] or (target>nums[left]>nums[mid] or\\\n",
    "             target<nums[mid]<nums[left]):\n",
    "                right=mid-1\n",
    "            elif nums[mid]<target<nums[right] or (target>nums[mid]>nums[right] or\\\n",
    "             nums[mid]>nums[right]>target):\n",
    "                left=mid+1\n",
    "            else:\n",
    "                right-=1\n",
    "                left+=1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> bool:\n",
    "        l = len(nums)\n",
    "\n",
    "        def binsearch(left, right):\n",
    "            if (left <= right):\n",
    "                mid = (left + right) // 2\n",
    "                if nums[mid] == target or nums[left] == target or nums[right] == target:\n",
    "                    return True\n",
    "                if nums[mid] == nums[left] and nums[mid] == nums[right]:\n",
    "                    return binsearch(left + 1, mid - 1) or binsearch(mid + 1, right - 1)\n",
    "\n",
    "                if nums[mid] == nums[right] and nums[mid] < nums[left]:\n",
    "                    return binsearch(left + 1, mid - 1)\n",
    "\n",
    "                if nums[mid] == nums[right] and nums[mid] > nums[left]:\n",
    "                    if target < nums[mid] and target > nums[left]:\n",
    "                        return binsearch(left + 1, mid - 1)\n",
    "                    else:\n",
    "                        return False\n",
    "\n",
    "                if nums[left] == nums[mid] and nums[mid] < nums[right]:\n",
    "                    if target > nums[mid] and target < nums[right]:\n",
    "                        return binsearch(mid + 1, right - 1)\n",
    "                    else:\n",
    "                        return False\n",
    "\n",
    "                if nums[left] == nums[mid] and nums[mid] > nums[right]:\n",
    "                    return binsearch(mid + 1, right - 1)\n",
    "\n",
    "                if nums[left] == nums[right] and nums[mid] > nums[left]:\n",
    "                    if target < nums[mid] and target > nums[left]:\n",
    "                        return binsearch(left + 1, mid - 1)\n",
    "                    else:\n",
    "                        return binsearch(mid + 1, right - 1)\n",
    "\n",
    "                if nums[left] == nums[right] and nums[mid] < nums[left]:\n",
    "                    if target > nums[mid] and target < nums[right]:\n",
    "                        return binsearch(mid + 1, right - 1)\n",
    "                    else:\n",
    "                        return binsearch(left + 1, mid - 1)\n",
    "\n",
    "                if nums[left] > nums[right] and nums[right] > nums[mid]:\n",
    "                    if target > nums[mid] and target < nums[right]:\n",
    "                        return binsearch(mid + 1, right - 1)\n",
    "                    else:\n",
    "                        return binsearch(left + 1, mid - 1)\n",
    "\n",
    "                if nums[left] > nums[right] and nums[mid] > nums[left]:\n",
    "                    if target<nums[mid] and target>nums[left]:\n",
    "                        return binsearch(left + 1, mid - 1)\n",
    "                    else:\n",
    "                        return binsearch(mid+1,right-1)\n",
    "\n",
    "                if nums[right] > nums[left]:\n",
    "                    if target < nums[mid] and target > nums[left]:\n",
    "                        return binsearch(left + 1, mid - 1)\n",
    "                    elif target > nums[mid] and target < nums[right]:\n",
    "                        return binsearch(mid + 1, right - 1)\n",
    "                    else:\n",
    "                        return False\n",
    "            return False\n",
    "\n",
    "        return binsearch(0, l - 1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> bool:\n",
    "        for i in range(1,len(nums)):\n",
    "            if nums[i] < nums[i-1]:\n",
    "                temp = nums[i:]\n",
    "                temp.extend(nums[:i])\n",
    "                nums = temp\n",
    "                break\n",
    "\n",
    "        def bisearch(l, r):\n",
    "            index = int((l+r)/2)\n",
    "            temp = nums[index]\n",
    "            print(nums[l:r+1], temp)\n",
    "            if target == temp:\n",
    "                return index\n",
    "            elif target == nums[l]:\n",
    "                return l\n",
    "            elif target == nums[r]:\n",
    "                return r\n",
    "            elif l>=r:\n",
    "                return -1\n",
    "            elif target > temp:\n",
    "                return bisearch(index+1, r)\n",
    "            elif target < temp:\n",
    "                return bisearch(l, index-1)\n",
    "                \n",
    "        if len(nums) > 0 and bisearch(0, len(nums)-1) >= 0:\n",
    "            return True\n",
    "        else:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> bool:\n",
    "        try:\n",
    "            if nums.index(target) >= 0:\n",
    "                return True\n",
    "            else:\n",
    "                return False\n",
    "        except:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> bool:\n",
    "        if not nums: return False\n",
    "        l, r = 0, len(nums)-1\n",
    "        n = len(nums)\n",
    "\n",
    "        while l <= r:\n",
    "            mid = l+(r-l) // 2\n",
    "            if nums[mid] == target:\n",
    "                return True\n",
    "            if nums[l] == nums[mid] and nums[mid] == nums[r]:\n",
    "                l += 1\n",
    "                r -= 1\n",
    "            elif nums[l] <= nums[mid]:\n",
    "                if nums[l] <= target < nums[mid]:\n",
    "                    r = mid - 1\n",
    "                else:\n",
    "                    l = mid + 1\n",
    "            else:\n",
    "                if nums[mid] < target <= nums[n - 1]:\n",
    "                    l = mid + 1\n",
    "                else:\n",
    "                    r = mid - 1\n",
    "        \n",
    "        return False\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> bool:\n",
    "        return target in nums"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> bool:\n",
    "        left,right = 0,len(nums)-1\n",
    "        while(left<=right):\n",
    "            mid = left + (right-left)//2\n",
    "            if nums[mid] == target:\n",
    "                return True\n",
    "            if nums[mid] == nums[left]: # 若中点和左端点的数字相同，我们无法判断哪个区间是增序的 \n",
    "                left+=1\n",
    "            elif nums[mid] <= nums[right]: # 说明右区间为有序的\n",
    "                if nums[mid] < target and nums[right]>=target:\n",
    "                    left = mid + 1\n",
    "                else:\n",
    "                    right = mid - 1\n",
    "            else:      # 说明左区间为有序的\n",
    "                if nums[mid] > target and nums[left] <= target:\n",
    "                    right = mid - 1\n",
    "                else:\n",
    "                    left = mid + 1\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> int:\n",
    "        left = 0\n",
    "        right = len(nums) - 1\n",
    "        while left <= right:\n",
    "            mid = (left + right) // 2\n",
    "            if nums[mid] == target:\n",
    "                return True\n",
    "            \n",
    "            if nums[mid] == nums[left] == nums[right]:\n",
    "                left += 1\n",
    "                right -= 1\n",
    "                continue\n",
    "            \n",
    "            if nums[mid] < nums[left]:\n",
    "                # 右有序\n",
    "                if nums[mid] < target <= nums[right]:\n",
    "                    left = mid + 1\n",
    "                else:\n",
    "                    right = mid - 1\n",
    "            else:\n",
    "                # 左有序\n",
    "                if nums[left] <= target < nums[mid]:\n",
    "                    right = mid - 1\n",
    "                else:\n",
    "                    left = mid + 1\n",
    "\n",
    "        return False\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> bool:\n",
    "        # for i in range (0,len(nums)):\n",
    "        #     if target==nums[i]:\n",
    "        #         return True\n",
    "        # return False\n",
    "\n",
    "        nums=list(set(nums))\n",
    "        l,r=0,len(nums)-1\n",
    "        while l<=r:\n",
    "            mid=(l+r)//2\n",
    "            if nums[mid]==target:\n",
    "                return True\n",
    "            if nums[l]<=nums[mid]:\n",
    "                if nums[l]<=target<nums[mid]:\n",
    "                    r=mid-1\n",
    "                else:\n",
    "                    l=mid+1\n",
    "            else:\n",
    "                if nums[mid]<target<=nums[r]:\n",
    "                    l=mid+1\n",
    "                else:\n",
    "                    r=mid-1\n",
    "        return False\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> bool:\n",
    "        def find(left=0,right=len(nums)-1,target=target,ret=False):\n",
    "            mid=(left+right)//2\n",
    "            if nums[mid]==target:\n",
    "                return True\n",
    "            if left<mid:\n",
    "                ret|=find(left,mid-1,target)\n",
    "                if ret:\n",
    "                    return True\n",
    "            if right>mid:\n",
    "                ret|=find(mid+1,right,target)\n",
    "                if ret:\n",
    "                    return True\n",
    "            return ret\n",
    "        return find()\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> bool:\n",
    "        if not nums:\n",
    "            return False\n",
    "        n=len(nums)\n",
    "        if n==1:\n",
    "            return nums[0]==target\n",
    "        l=0\n",
    "        r=n-1\n",
    "        while l<=r:\n",
    "            mid=(l+r)//2\n",
    "            if nums[mid]==target:\n",
    "                return True\n",
    "            if nums[l]==nums[mid] and nums[mid]==nums[r]: \n",
    "                # 无法判断哪个区间有序于是缩小当前区间再二分\n",
    "                l+=1\n",
    "                r-=1\n",
    "            elif nums[l]<=nums[mid]:\n",
    "                if nums[l]<=target<nums[mid]:\n",
    "                    r=mid-1\n",
    "                else:\n",
    "                    l=mid+1\n",
    "            else:\n",
    "                if nums[mid]<target<=nums[n-1]:\n",
    "                    l=mid+1\n",
    "                else:\n",
    "                    r=mid-1\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> bool:\n",
    "        left=0\n",
    "        right=len(nums)-1\n",
    "        if len(nums)==1:\n",
    "            return nums[0]==target\n",
    "        while left<=right:\n",
    "            mid=(left+right)//2\n",
    "            if nums[mid]==target:\n",
    "                return True\n",
    "            if nums[left]==nums[mid]==nums[right]:\n",
    "                left+=1\n",
    "                right-=1\n",
    "            elif nums[mid]>=nums[left]:\n",
    "                if nums[left]<=target<=nums[mid]:\n",
    "                    right=mid-1\n",
    "                else:\n",
    "                    left=mid+1\n",
    "            elif nums[mid]<=nums[right]:\n",
    "                if nums[mid]<target<=nums[right]:\n",
    "                    left=mid+1\n",
    "                else:\n",
    "                    right=mid-1\n",
    "        else:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> bool:\n",
    " # *二分。每次二分前要首尾去重，不然难以判断是否【有序】\n",
    "        n=len(nums)\n",
    "        if nums is None or n==0:\n",
    "            return False\n",
    "        l,r=0,n-1\n",
    "        while l<=r:\n",
    "            m=l+(r-l)//2\n",
    "            if target==nums[m]:\n",
    "                return True\n",
    "            # 每次二分前要首尾去重，不然难以判断是否【有序】\n",
    "            if nums[m]==nums[l]:\n",
    "                l+=1\n",
    "                continue\n",
    "            if nums[m]==nums[r]:\n",
    "                r-=1\n",
    "                continue\n",
    "\n",
    "            #\n",
    "            if nums[l]<nums[m]:\n",
    "                # if nums[l]<target<nums[m]:\n",
    "                if nums[l]<=target<nums[m]:\n",
    "                    r=m-1\n",
    "                else:\n",
    "                    l=m+1\n",
    "            else:\n",
    "                # if nums[m]<target<nums[r]:\n",
    "                if nums[m]<target<=nums[r]:\n",
    "                    l=m+1\n",
    "                else:\n",
    "                    r=m-1\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        new = dict((nums[i],i) for i in range(len(nums)))\n",
    "        if new.get(target) == 0:\n",
    "            return 0\n",
    "        else:\n",
    "            return new.get(target) or -1\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums, target):\n",
    "        left, right = 0, len(nums)-1\n",
    "\n",
    "        while left <= right:\n",
    "            mid = (left+right)//2\n",
    "            if nums[mid] == target:\n",
    "                return mid\n",
    "            if nums[mid] < nums[right]:\n",
    "                if nums[mid] < target and target <= nums[right]:\n",
    "                    left = mid+1\n",
    "                else:\n",
    "                    right = mid-1\n",
    "            else:\n",
    "                if nums[left] <= target and target < nums[mid]:\n",
    "                    right = mid-1\n",
    "                else:\n",
    "                    left = mid+1\n",
    "\n",
    "        return -1\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums, target):\n",
    "        \"\"\"\n",
    "        33. Search in Rotated Sorted Array\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        p,r=0,len(nums)-1\n",
    "        while p<=r:\n",
    "            print(p,r)\n",
    "            q=int((p+r)/2)\n",
    "            if target==nums[q]:\n",
    "                return q\n",
    "\n",
    "            if nums[p]<nums[q]:\n",
    "                if target>= nums[p] and target<=nums[q-1]:\n",
    "                    r=q-1\n",
    "                else:\n",
    "                    p=q+1\n",
    "            else:\n",
    "                if q+1<len(nums) and target>=nums[q+1] and target<=nums[r]:\n",
    "                    p=q+1\n",
    "                else:\n",
    "                    r=q-1\n",
    "        return -1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        l,r=0,len(nums)-1\n",
    "        while(l<=r):\n",
    "            mid=(l+r)//2\n",
    "            if nums[mid]==target:\n",
    "                return mid\n",
    "            if nums[-1]>nums[mid]:#mid in right part [][m t] [][t m] [t][m],take [][m t] as condition.\n",
    "                #besides, [] can be null,thus corner case is also considerd.\n",
    "                if target<=nums[-1] and target>nums[mid]:\n",
    "                    l=mid+1\n",
    "                else:\n",
    "                    r=mid-1\n",
    "            else:#mid in left part,[m t][],[t m][], [m][t]\n",
    "                if target<nums[mid] and target>=nums[0]:\n",
    "                    r=mid-1\n",
    "                else:\n",
    "                    l=mid+1\n",
    "        return -1         "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        n = len(nums)\n",
    "        if not n: return -1\n",
    "\n",
    "        def binarySearch(start, end):\n",
    "            if start == end:\n",
    "                return end if nums[end] == target else -1\n",
    "            median = (start + end + 1)//2\n",
    "            if nums[start] < nums[median]:\n",
    "                if nums[start] < target <= nums[median]:\n",
    "                    return binarySearch(start+1, median)\n",
    "                elif nums[start] == target:\n",
    "                    return start\n",
    "                else:\n",
    "                    return binarySearch(median, end)\n",
    "            elif nums[start] > nums[median]:\n",
    "                if nums[start] > target >= nums[median]:\n",
    "                    return binarySearch(median, end)\n",
    "                elif nums[start] == target:\n",
    "                    return start\n",
    "                else:\n",
    "                    return binarySearch(start+1, median)\n",
    "\n",
    "        return binarySearch(0, n-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> int:\n",
    "        if(len(nums)==0):\n",
    "            return -1\n",
    "        if(len(nums)==1):\n",
    "            if(nums[0]==target):\n",
    "                return 0\n",
    "            else:\n",
    "                return -1\n",
    "        left = 0\n",
    "        right = len(nums)-1\n",
    "        while(left<right):\n",
    "            middle = int((left+right)/2)\n",
    "            if(nums[middle]==target):\n",
    "                return middle\n",
    "            if(nums[left]<=nums[middle]):#左升序\n",
    "                if(target<nums[middle] and target>=nums[left]):\n",
    "                    left = left\n",
    "                    right = middle-1\n",
    "                else:\n",
    "                    left = middle+1\n",
    "                    right = right\n",
    "            else:#右升序\n",
    "                if(target<=nums[right] and target>nums[middle]):\n",
    "                    left = middle+1\n",
    "                    right = right\n",
    "                else:\n",
    "                    left = left\n",
    "                    right = middle-1\n",
    "        if(nums[left]==target):\n",
    "            return left\n",
    "        else:\n",
    "            return -1\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        if len(nums) == 0:\n",
    "            return -1\n",
    "        if nums[0] == target:\n",
    "            return 0\n",
    "        for i in range(1, len(nums)):\n",
    "            print(i)\n",
    "            if nums[i] == target:\n",
    "                return i\n",
    "            elif target > nums[i-1] and nums[i] < nums[i-1]:\n",
    "                break;\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> int:\n",
    "        ## another solution is using twice divided \n",
    "        # the first one is to find min() then...\n",
    "        j=len(nums)-1\n",
    "        if j+1==0:\n",
    "            return-1\n",
    "        elif j+1==1:\n",
    "            return 0 if nums[0]==target else -1\n",
    "        elif j+1==2:\n",
    "            if nums[0]==target:\n",
    "                return 0\n",
    "            elif nums[1]==target:\n",
    "                return 1\n",
    "            else:\n",
    "                return-1\n",
    "        low=0\n",
    "        up=j\n",
    "        while low<=up:\n",
    "            mid=(low+up)//2\n",
    "            if target==nums[mid]:\n",
    "                return mid\n",
    "            if nums[low]<=nums[mid]:\n",
    "                if target>=nums[low] and target<nums[mid]:\n",
    "                    up=mid-1\n",
    "                else:\n",
    "                    low=mid+1\n",
    "            else:\n",
    "                if target>nums[mid] and target<=nums[up]:\n",
    "                    low=mid+1\n",
    "                else:\n",
    "                    up=mid-1\n",
    "        return -1\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> int:\n",
    "        if not nums:\n",
    "            return -1\n",
    "        length = len(nums)\n",
    "        if length == 1 and target == nums[0]:\n",
    "            return 0\n",
    "        if length == 1 and target != nums[0]:\n",
    "            return -1\n",
    "        mid = length//2\n",
    "        left = mid\n",
    "        right = mid\n",
    "        if nums[mid] > nums[0]:\n",
    "            while  right+1 < length and nums[right+1] > nums[right]:\n",
    "                right += 1\n",
    "            min_index = right + 1\n",
    "            if target >= nums[0]:\n",
    "                l1 = 0\n",
    "                r1 = right\n",
    "                while l1 <= r1:\n",
    "                    mid_l = (l1 + r1)//2\n",
    "                    if target == nums[mid_l]:\n",
    "                        return mid_l\n",
    "                    elif target < nums[mid_l]:\n",
    "                        r1 = mid_l - 1\n",
    "                    elif target > nums[mid_l]:\n",
    "                        l1 = mid_l + 1\n",
    "                if l1 > r1:\n",
    "                    return -1\n",
    "            else:\n",
    "                l1 = min_index\n",
    "                r1 = length - 1\n",
    "                while l1 <= r1:\n",
    "                    mid_l = (l1 + r1)//2\n",
    "                    if target == nums[mid_l]:\n",
    "                        return mid_l\n",
    "                    elif target < nums[mid_l]:\n",
    "                        r1 = mid_l - 1\n",
    "                    elif target > nums[mid_l]:\n",
    "                        l1 = mid_l + 1\n",
    "                if l1 > r1:\n",
    "                    return -1\n",
    "        else:\n",
    "            while  left-1 >= 0 and  nums[left-1] < nums[left]:\n",
    "                left -= 1\n",
    "            min_index = left\n",
    "            if target >= nums[0]:\n",
    "                l1 = 0\n",
    "                r1 = left - 1\n",
    "                while l1 <= r1:\n",
    "                    mid_l = (l1 + r1)//2\n",
    "                    if target == nums[mid_l]:\n",
    "                        return mid_l\n",
    "                    elif target < nums[mid_l]:\n",
    "                        r1 = mid_l - 1\n",
    "                    elif target > nums[mid_l]:\n",
    "                        l1 = mid_l + 1\n",
    "                if l1 > r1:\n",
    "                    return -1\n",
    "            else:\n",
    "                l1 = left\n",
    "                r1 = length - 1\n",
    "                while l1 <= r1:\n",
    "                    mid_l = (l1 + r1)//2\n",
    "                    if target == nums[mid_l]:\n",
    "                        return mid_l\n",
    "                    elif target < nums[mid_l]:\n",
    "                        r1 = mid_l - 1\n",
    "                    elif target > nums[mid_l]:\n",
    "                        l1 = mid_l + 1\n",
    "                if l1 > r1:\n",
    "                    return -1\n",
    "\n",
    "    \n",
    "\n",
    "        \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> int:\n",
    "        if len(nums) == 0:\n",
    "            return -1\n",
    "\n",
    "        if len(nums) == 1 and target != nums[0]:\n",
    "            return -1\n",
    "\n",
    "        if target == nums[0]:\n",
    "            return 0\n",
    "\n",
    "        elif target < nums[0]:\n",
    "            if nums[0] <= nums[-1]:\n",
    "                return -1\n",
    "            else:\n",
    "                count = len(nums)-1\n",
    "                while target < nums[count] and nums[count] < nums[0]:\n",
    "                    count -= 1\n",
    "                if target == nums[count]:\n",
    "                    return count\n",
    "                else:\n",
    "                    return -1\n",
    "        \n",
    "        else:\n",
    "            count = 0\n",
    "            while target > nums[count] and nums[count] >= nums[0]:\n",
    "                count += 1\n",
    "                if count >= len(nums)-1:\n",
    "                    break\n",
    "            if target == nums[count]:\n",
    "                return count\n",
    "            else:\n",
    "                return -1\n",
    "            \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, lst: List[int], x: int) -> int:\n",
    "        length = len(lst)\n",
    "        if length == 0:\n",
    "            return -1\n",
    "        start = lst[0]\n",
    "        pointer = length//2\n",
    "        l, r = 0, length-1\n",
    "        if x == start:\n",
    "            return 0\n",
    "        while l <= r:\n",
    "            pointer = (l+r)//2\n",
    "            if lst[pointer] == x:\n",
    "                return pointer\n",
    "            if x > start and lst[pointer] > x:\n",
    "                r = pointer -1\n",
    "            elif x > start and lst[pointer] < x and lst[pointer] >= start:\n",
    "                l = pointer +1\n",
    "            elif x > start and lst[pointer] < x and lst[pointer] < start:\n",
    "                r = pointer -1\n",
    "            elif x <= start and  lst[pointer] > x and  lst[pointer] < start:\n",
    "                r = pointer -1\n",
    "            elif x <= start and  lst[pointer] > x and  lst[pointer] >= start:\n",
    "                l = pointer +1 \n",
    "            elif x <= start and  lst[pointer] < x:\n",
    "                l = pointer +1\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> int:\n",
    "        low, high = 0, len(nums)-1\n",
    "\n",
    "        while(low <= high):\n",
    "            mid = (low + high) // 2\n",
    "\n",
    "            if nums[mid] == target:\n",
    "                return mid \n",
    "\n",
    "            if nums[mid] > nums[high]:\n",
    "                if nums[low] <= target and target < nums[mid]:\n",
    "                    high = mid - 1\n",
    "                else:\n",
    "                    low = mid + 1\n",
    "            else:\n",
    "                if nums[mid] < target and target <= nums[high]:\n",
    "                    low = mid + 1 \n",
    "                else:\n",
    "                    high = mid - 1\n",
    "\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "# 如果中间的数小于最右边的数，则右半段是有序的，若中间数大于最右边数，则左半段是有序的，我们只# 要在有序的半段里用首尾两个数组来判断目标值是否在这一区域内，这样就可以确定保留哪半边了\n",
    "    def search(self, nums: List[int], target: int) -> int:\n",
    "        n = len(nums)\n",
    "        l = 0;r = n-1\n",
    "        while l <= r:\n",
    "            mid = (l+r)>>1\n",
    "            if nums[mid] == target:\n",
    "                return mid\n",
    "            elif nums[l] <= nums[mid]:\n",
    "                if nums[l] <= target < nums[mid]:\n",
    "                    r = mid-1\n",
    "                else:\n",
    "                    l = mid + 1\n",
    "            else:\n",
    "                if nums[mid] < target <= nums[n-1]:\n",
    "                    l = mid + 1\n",
    "                else:\n",
    "                    r = mid-1\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> int:\n",
    "        # time O(logn), space O(1)\n",
    "        if not nums: return -1\n",
    "        left, right = 0, len(nums)-1\n",
    "        while left < right:\n",
    "            mid = left + (right-left+1)//2\n",
    "            \n",
    "            if nums[left] <= nums[mid]:\n",
    "                if nums[left]<= target <= nums[mid-1]:\n",
    "                    right = mid-1\n",
    "                else:\n",
    "                    left = mid\n",
    "            else:\n",
    "                if nums[mid] <= target <= nums[right]:\n",
    "                    left = mid\n",
    "                else:\n",
    "                    right = mid-1\n",
    "            \n",
    "        if nums[left] == target:\n",
    "            return left\n",
    "        else:\n",
    "            return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> int:\n",
    "        n=len(nums)\n",
    "        left,right=0,n-1\n",
    "        while left<=right:\n",
    "            mid=left+(right-left)//2\n",
    "            if nums[mid]==target:\n",
    "                return mid\n",
    "            if nums[mid]>=nums[0]:\n",
    "                if target>=nums[0] and target<nums[mid]:\n",
    "                    right=mid-1\n",
    "                else:\n",
    "                    left=mid+1\n",
    "            else:\n",
    "                if nums[mid]<target<=nums[n-1]:\n",
    "                    left=mid+1\n",
    "                else:\n",
    "                    right=mid-1\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> int:\n",
    "        def binsearch(nums,target,start,end):\n",
    "            if start==end and nums[start] != target:\n",
    "                return -1\n",
    "            mid = (start+end)//2\n",
    "            if nums[mid] < target:\n",
    "                return binsearch(nums,target,mid+1,end)\n",
    "            elif nums[mid] > target:\n",
    "                return binsearch(nums,target,start,mid)\n",
    "            else:\n",
    "                return mid\n",
    "        pivot = 0\n",
    "        n = len(nums)\n",
    "        if n == 1:\n",
    "            if nums[0] == target:\n",
    "                return 0\n",
    "            else:\n",
    "                return -1\n",
    "        while pivot < n - 1 and nums[pivot] < nums[pivot+1]:\n",
    "            pivot += 1\n",
    "        if pivot == n - 1:\n",
    "            return binsearch(nums,target,0,pivot)\n",
    "        if nums[0] <= target and target <= nums[pivot]:\n",
    "            return binsearch(nums,target,0,pivot)\n",
    "        else:\n",
    "            return binsearch(nums,target,pivot+1,n-1)\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "\n",
    "class Solution:\n",
    "    @staticmethod\n",
    "    def binary_search(alist, item):\n",
    "        n = len(alist)\n",
    "        start = 0\n",
    "        end = n - 1\n",
    "        while start <= end:\n",
    "            mid = (start + end) // 2\n",
    "            if alist[mid] == item:\n",
    "                return mid\n",
    "            elif item < alist[mid]:\n",
    "                end = mid - 1\n",
    "            else:\n",
    "                start = mid + 1\n",
    "        return -1\n",
    "\n",
    "    def search(self, nums: List[int], target: int) -> int:\n",
    "\n",
    "        le = 0\n",
    "        ri = len(nums) - 1\n",
    "        if len(nums) <= 1:\n",
    "            if target in nums:\n",
    "                return 0\n",
    "            return -1\n",
    "        if len(nums) == 2:\n",
    "            if target in nums:\n",
    "                return 0 if nums[0] == target else 1\n",
    "            return -1\n",
    "        def bin_search(l, r):\n",
    "            if nums[l] < nums[r]:\n",
    "                rt = Solution.binary_search(nums[l:r+1], target)\n",
    "                if rt >= 0:\n",
    "                    rt = rt + l\n",
    "                return rt\n",
    "            else:\n",
    "                midd = (l + r) // 2\n",
    "                if nums[midd] == target:\n",
    "                    return midd\n",
    "                if midd < len(nums) - 1 and midd + 1 <= r:\n",
    "                    a = bin_search(midd + 1, r)\n",
    "                    if a >= 0:\n",
    "                        return a\n",
    "                if midd - 1 >= 0 and l <= midd - 1:\n",
    "                    b = bin_search(l, midd-1)\n",
    "                    if b >= 0:\n",
    "                        return b\n",
    "                return -1\n",
    "\n",
    "        return bin_search(le, ri)\n",
    "\n",
    "\n",
    "# s = Solution()\n",
    "# nums = [4,5,6,7,0,1,2]\n",
    "# numss = [3,5,1]\n",
    "#\n",
    "# print(s.search(numss, 0))\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from functools import lru_cache\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> int:\n",
    "        if len(nums) == 1:\n",
    "            return 0 if nums[0] == target else -1\n",
    "        @lru_cache(None)\n",
    "        def find(i, j):\n",
    "            if j == i + 1:\n",
    "                if nums[j] < nums[i]:\n",
    "                    return j\n",
    "                else:\n",
    "                    return -1\n",
    "            else:\n",
    "                tmp = (j + i) // 2\n",
    "                return max(find(i, tmp), find(tmp, j))\n",
    "        tmp = find(0, len(nums)-1)\n",
    "        if target >= nums[0]:\n",
    "            index = bisect.bisect_left(nums[: tmp], target)\n",
    "        else:\n",
    "            index = tmp + bisect.bisect_left(nums[tmp:], target)\n",
    "        if index < len(nums) and nums[index] == target:\n",
    "            return index\n",
    "        else:\n",
    "            return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> int:\n",
    "        if target in nums:\n",
    "            return nums.index(target)\n",
    "        else:\n",
    "            return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> int:\n",
    "        if not nums:\n",
    "            return -1\n",
    "        l = 0\n",
    "        r = len(nums)-1\n",
    "        while l <= r:\n",
    "            mid = (l+r)//2\n",
    "            if nums[mid] == target:\n",
    "                return mid\n",
    "            if nums[mid] >= nums[l]:\n",
    "                if nums[l] <= target < nums[mid]:\n",
    "                    r = mid - 1\n",
    "                else:\n",
    "                    l = mid + 1\n",
    "            else:\n",
    "                if nums[mid] < target <= nums[r]:\n",
    "                    l = mid + 1\n",
    "                else:\n",
    "                    r = mid - 1\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> int:\n",
    "        n = len(nums)\n",
    "        left, right = 0, n-1\n",
    "        while left <= right:\n",
    "            mid = (left + right) // 2\n",
    "            if nums[mid] == target:\n",
    "                return mid\n",
    "            elif nums[0] <= nums[mid]:\n",
    "                if nums[0] <= target <= nums[mid]:\n",
    "                    right = mid - 1\n",
    "                else:\n",
    "                    left = mid + 1\n",
    "            elif nums[0] > nums[mid]:\n",
    "                if nums[mid] <= target <= nums[right]:\n",
    "                    left = mid + 1\n",
    "                else:\n",
    "                    right = mid -1\n",
    "        return -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> int:\n",
    "        if not nums:\n",
    "            return -1\n",
    "        left  = 0\n",
    "        right = len(nums) - 1\n",
    "        while left < right:\n",
    "            mid = left + (right - left) // 2\n",
    "            if target == nums[mid]:\n",
    "                return mid\n",
    "            if nums[left] <= nums[mid]:\n",
    "                if nums[left] <= target < nums[mid]:\n",
    "                    right = mid\n",
    "                else:\n",
    "                    left = mid + 1\n",
    "            else:\n",
    "                if nums[mid] < target <= nums[right]:\n",
    "                    left = mid + 1\n",
    "                else:\n",
    "                    right = mid\n",
    "        return left if nums[left]==target else -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> int:\n",
    "        if len(nums)==1:\n",
    "            if nums[0] == target: return 0\n",
    "            else: return -1\n",
    "        if len(nums)==2:\n",
    "            if nums[0] == target: return 0\n",
    "            elif nums[1] == target: return 1\n",
    "            else: return -1 \n",
    "\n",
    "\n",
    "        left, right = 0, len(nums)-1\n",
    "        while left < right:\n",
    "            mid = (left+right)//2+1\n",
    "            if nums[mid] > nums[left]:\n",
    "                left = mid\n",
    "            else:\n",
    "                right = mid - 1\n",
    "\n",
    "        k = left\n",
    "        if k == len(nums)-1:\n",
    "            nums2 = nums[:]\n",
    "            res = 0\n",
    "        elif nums[0] > target:\n",
    "            nums2 = nums[k+1:]\n",
    "            res = k+1\n",
    "        else: \n",
    "            nums2 = nums[:k+1]\n",
    "            res = 0\n",
    "        \n",
    "        print(nums2,res,k)\n",
    "\n",
    "        left, right = 0, len(nums2)-1\n",
    "        while left <= right:\n",
    "            mid = (left+right)//2\n",
    "            if nums2[mid] == target:\n",
    "                return res + mid\n",
    "            if nums2[mid] > target:\n",
    "                right = mid - 1\n",
    "            if nums2[mid] < target:\n",
    "                left = mid + 1\n",
    "        return -1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def search(self, nums: List[int], target: int) -> int:\r\n",
    "        sort_nums = []\r\n",
    "        for i in range(len(nums)):\r\n",
    "            sort_nums.append([nums[i],i])\r\n",
    "        sort_nums.sort()\r\n",
    "        nums.sort()\r\n",
    "\r\n",
    "        def bi_search(start,end):\r\n",
    "            mid = (start+end)//2\r\n",
    "\r\n",
    "            if start==end:\r\n",
    "                return mid if nums[mid]==target else -1\r\n",
    "\r\n",
    "            if nums[mid]>=target:\r\n",
    "                return bi_search(start,mid)\r\n",
    "            else:\r\n",
    "                return bi_search(mid+1,end)\r\n",
    "        \r\n",
    "        idx = bi_search(0,len(nums)-1)\r\n",
    "        return sort_nums[idx][1] if idx!= -1 else -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> int:\n",
    "\n",
    "        # 核心思想：翻转列表二分之后包含有序的一部分和无序的一部分，我们只看有序的那部分即可，满足不了再看无序的部分.最终必然会在有序的部分找到目标值\n",
    "\n",
    "        l , r = 0 , len(nums) - 1\n",
    "\n",
    "        while l <= r:\n",
    "            mid = (l+r) // 2\n",
    "\n",
    "            if nums[mid] == target:\n",
    "                return mid\n",
    "            \n",
    "            if nums[0] <= nums[mid]:\n",
    "                # 此时左边是有序的,只判断左边，不满足则再从右边找\n",
    "                if nums[0] <= target < nums[mid]:\n",
    "                    r = mid-1\n",
    "                else:\n",
    "                    # 此时只能从无序的部分重新开始找\n",
    "                    l = mid+1\n",
    "\n",
    "            else:\n",
    "                # 此时右边是有序的\n",
    "                if nums[mid] < target <=nums[r]:\n",
    "                    l = mid + 1\n",
    "\n",
    "                else:\n",
    "                    r = mid -1 \n",
    "\n",
    "        return -1\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> int:\n",
    "        def is_blue(i: int) -> bool:\n",
    "            end = nums[-1]\n",
    "            if nums[i] > end:\n",
    "                return target > end and nums[i] >= target\n",
    "            else:\n",
    "                return target > end or nums[i] >= target\n",
    "\n",
    "        left, right = -1, len(nums)  # 开区间 (-1, n)\n",
    "        while left + 1 < right:  # 开区间不为空\n",
    "            mid = (left + right) // 2\n",
    "            if is_blue(mid):  # 蓝色\n",
    "                right = mid\n",
    "            else:  # 红色\n",
    "                left = mid\n",
    "        return right if right < len(nums) and nums[right] == target else -1\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def search(self, nums: List[int], target: int) -> int:\n",
    "        n = len(nums)\n",
    "        # if n == 0:\n",
    "        #     return -1\n",
    "        # if n == 1:\n",
    "        #     return 0 if nums[0] == target else -1\n",
    "        l, r = 0, n - 2\n",
    "        while l <= r:\n",
    "            m = l + (r - l) // 2\n",
    "            if nums[m] >= nums[-1]:\n",
    "                l = m + 1\n",
    "            else:\n",
    "                r = m - 1\n",
    "        if target <= nums[-1]:\n",
    "            r = n - 1\n",
    "\n",
    "        else:\n",
    "            l = 0\n",
    "        while l <= r:\n",
    "            m = l + r >> 1\n",
    "            if nums[m] >= target:\n",
    "                r = m - 1\n",
    "            else:\n",
    "                l = m + 1\n",
    "        return l if nums[l] == target else -1"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 2
}
